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

时间:2010-08-25 22:32:34

标签: regex

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

kg/m^3

对密度或

有效

m/s^2

加速。

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

3 个答案:

答案 0 :(得分: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
          )
      )*
  )?
)

我把升作为一个单位包括在内,即使它不是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 + ")?"

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

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

答案 1 :(得分:1)

HHm,我不认为正则表达式可以在一般意义上表达,而是应该使用无上下文的形式主义。

但是,您可以按照通常的类型执行此操作。

这个注册。进出口。将为您的示例和这些做一些事情(如果您愿意的话,将每个\d+替换为一些reg.exp。小数:)

kg^2/m^3
kg*2/m
kg^2*2*m/m^3
kg/m/kg^3

(kg|m|s|A|K|cd|mol|\d+)((\*|\^)(kg|m|s|A|K|cd|mol|\d+))*(/(kg|m|s|A|K|cd|mol|\d+)((\*|\^)(kg|m|s|A|K|cd|mol|\d+))*)?

但不是这样的:

kg^(kg/m)/m/kg^3

python中的单位:

Unit Conversion in Python

答案 2 :(得分:1)

这个是相关的 RegEx for distance in metric system。 您只需要为可选分母和指数扩展正则表达式。