有效SI单位的正则表达式(国际单位制)

unm*_*ted 2 regex

我正在寻找一个正则表达式来检查http表单中的有效SI单位输入.所以,例如,

kg/m^3

对密度有效

m/s^2

加速.

这似乎是一些开放式图书馆可能已经解决的问题; 或者从一组有限的基本单位开始,可能有一种聪明的方法.它适用于要求用户遵循特定输入规则的学术环境.

nd.*_*nd. 9

纯正则表达式解决方案有点不优雅,因为它必须多次重复捕获以适应乘法和除法:

(?x)
(    # Capture 1: the entire matched composed unit string
  (  # Capture 2: one unit including the optional prefix
    (Y|Z|E|P|T|G|M|k|h|da|d|c|m|µ|n|p|f|a|z|y)?  # Capture 3: optional prefix, taken from http://en.wikipedia.org/wiki/SI_prefix
    (m|g|s|A|K|mol|cd|Hz|N|Pa|J|W|C|V|F|?|S|Wb|T|H|lm|lx|Bq|Gy|Sv|kat|l|L) # Capture 4: Base units and derived units w/o °C, rad and sr, but with L/l for litre
    (\^[+-]?[1-9]\d*)? # Capture 5: Optional power with optional sign. \^0 and \^-0 are not permitted
  |                 # or
    1               # one permitted, e.g. in 1/s
  )
  (?:    # Zero or more repetitions of one unit, plus the multiplication sign
     ·(  # Capture 6: one unit including the optional prefix
        (Y|Z|E|P|T|G|M|k|h|da|d|c|m|µ|n|p|f|a|z|y)?  # Capture 7
        (m|g|s|A|K|mol|cd|Hz|N|Pa|J|W|C|V|F|?|S|Wb|T|H|lm|lx|Bq|Gy|Sv|kat|l|L) # Capture 8
        (\^[+-]?[1-9]\d*)? # Capture 9
      |                 # or
        1               # one permitted, e.g. in 1/s
      )
  )*
  (?:    # Optional: possibly multiplied units underneath a denominator sign
      \/(  # Capture 10
        (Y|Z|E|P|T|G|M|k|h|da|d|c|m|µ|n|p|f|a|z|y)?  # Capture 11
        (m|g|s|A|K|mol|cd|Hz|N|Pa|J|W|C|V|F|?|S|Wb|T|H|lm|lx|Bq|Gy|Sv|kat|l|L) # Capture 12
        (\^[+-]?[1-9]\d*)? # Capture 13
      |                 # or
        1               # one permitted, e.g. in 1/s
      )
      (?:    # Zero or more repetitions of one unit, plus the multiplication sign
         ·(  # Capture 14
            (Y|Z|E|P|T|G|M|k|h|da|d|c|m|µ|n|p|f|a|z|y)?  # Capture 15
            (m|g|s|A|K|mol|cd|Hz|N|Pa|J|W|C|V|F|?|S|Wb|T|H|lm|lx|Bq|Gy|Sv|kat|l|L) # Capture 16
            (\^[+-]?[1-9]\d*)? # Capture 17
          |                 # or
            1               # one permitted, e.g. in 1/s
          )
      )*
  )?
)
Run Code Online (Sandbox Code Playgroud)

虽然它不是SI单位,但我把升作为一个整体包括在内.我还需要标准的乘法符号.如果需要,您可以修改它.如果从几个基本字符串构造正则表达式,则更容易掌握:

prefix = "(Y|Z|E|P|T|G|M|k|h|da|d|c|m|µ|n|p|f|a|z|y)"
unit = "(m|g|s|A|K|mol|cd|Hz|N|Pa|J|W|C|V|F|?|S|Wb|T|H|lm|lx|Bq|Gy|Sv|kat|l|L)"
power = "(\^[+-]?[1-9]\d*)"
unitAndPrefix = "(" + prefix + "?" + unit + power + "?" + "|1" + ")"
multiplied = unitAndPrefix + "(?:·" + unitAndPrefix + ")*"
withDenominator = multiplied + "(?:\/" + multiplied + ")?"
Run Code Online (Sandbox Code Playgroud)

正则表达式不进行任何一致性检查,当然,它也接受诸如kg ^ -1·kg ^ -1·1/kg ^ -2之类的东西作为有效.

当然,您可以根据需要修改正则表达式,例如使用*乘法字符等.