繁体   English   中英

Reg Ex表示字符串中的特定数字

[英]Reg Ex for specific number in string

我想匹配字符串中的数字(整数和实数),但是如果它们是标识符的一部分,则不希望匹配; 例如,我想匹配5.5或42,但不匹配x5。 字符串的格式大致为“ x5 * 1.1 + 42 * y = 40”。 到目前为止,我想到了

([0-9]*[.])?[0-9]+[^.*+=<>]

这将正确地忽略x0,但也忽略0或0.5(但是,可以使用12.45)。 +更改为*会导致错误的匹配。

如果有人可以指出我的错误,那就太好了。

谢谢!

这实际上并不简单。 浮点文字比您想象的要复杂,它可以包含eE的指数格式。 同样,您可以在数字和/或指数前加上前缀符号( +- )。 总而言之,可以这样完成:

re.findall(r'(?:(?<![a-zA-Z_0-9])|[+-]\s*)[\d.]+(?:[eE][+-]?\d+)?',
           'x5*1.1+42*y=40+a123-3.14e-2')

返回:

['1.1', '+42', '40', '-3.14e-2']

您应该考虑是否应该像4+3这样的结果导致['4', '3']['4', '-3'] 如果输入为4+-3则显然最好使用'-3' 但是要区分这些并不容易,您应该考虑使用适当的公式解析器。

也许标准模块ast可以为您提供帮助。 在这种情况下,该表达式必须是有效的Python表达式,因此不允许使用a+b=40类的东西,因为等号左边没有适当的左值 但是对于有效的Python对象,您可以这样使用ast

import ast

def find_all_numbers(e):
  if isinstance(e, ast.BinOp):
    for r in find_all_numbers(e.left):
      yield r
    for r in find_all_numbers(e.right):
      yield r
  elif isinstance(e, ast.Num):
    yield e.n

list(find_all_numbers(ast.parse('x5*1.1+42*y-40').body[0].value))

返回值:

[1.1, 42, 40]

你可以用类似的东西做

\b\d*(\.\d+)?\b

它匹配任意数量的数字( \\d* ),后跟可选的小数部分( (\\.\\d+)? )。 \\b匹配单词边界 ,即单词字符和单词字符之间的位置。 而且由于数字和(英文)字母都是单词字符 ,因此它不会像x5那样与5匹配。

请参见此regex101示例

尝试失败的主要原因是它以[^.*+=<>]结尾,要求数字 (或更确切地说是match )以非字符结尾. *=+<> 并且当以00.5等单个数字结尾时,该数字会 [0-9]+吞噬,并且没有余数匹配左[^.*+=<>] ,因此它失败了。 12.45的情况下,它首先匹配12.4 ,然后[^.*+=<>]匹配5

做类似((?<![a-zA-Z_])\\d+(\\.\\d+)?)

它使用负向后看,以便不选择之前具有[a-zA-Z_]任何内容。 Regex101中检查一下。

关于您的正则表达式([0-9]*[.])?[0-9]+[^.*+=<>]使用[0-9]+而不是[0-9]*因为它不允许.05被捕获,只有0.5。 另一件事是[^.*+=<>]这一部分,您可以添加? 到它的末尾,以允许它也没有字符。 1.1不会被捕获,因为([0-9]*[.])?[0-9]+被满足,但紧随其后的是[^.*+=<>]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM