我正在寻找一个正则表达式来检查http表单中的有效SI单位输入。例如,
kg/m^3
对密度或
有效 m/s^2
加速。
似乎某些开放式图书馆可能已经解决了这类问题;或者从一组有限的基本单位开始,可能有一种聪明的方法。它适用于要求用户遵循特定输入规则的学术环境。
答案 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中的单位:
答案 2 :(得分:1)
这个是相关的 RegEx for distance in metric system。 您只需要为可选分母和指数扩展正则表达式。