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

时间:2017-12-12 14:26:20

标签: python regex

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

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

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

如果有人可以指出我的错误,那将是非常好的。

谢谢!

3 个答案:

答案 0 :(得分:1)

这实际上并不简单。 Float文字比您假设的更复杂,能够包含指数格式的Channele。此外,您可以为数字和/或指数添加带前缀的符号(E+)。总而言之,它可以这样做:

-

返回:

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'可以帮助您。在这种情况下,表达式必须是有效的Python表达式,因此不允许使用ast之类的东西,因为等号左边没有正确的 lvalue 。但对于有效的Python对象,您可以使用a+b=40,如下所示:

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 :(得分:0)

你可以用

之类的东西来做
\b\d*(\.\d+)?\b

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

See this regex101 example

尝试失败的主要原因是它以[^.*+=<>]结尾,要求数字(或者更确切地说匹配)以{以外的字符结尾}结束{1}},.*=+<。当以>0之类的单个数字结尾时,数字会被0.5 吃掉,而且与{{1}无关离开了,因此失败了。在[0-9]+的情况下,它首先与[^.*+=<>]匹配,然后12.4512.4匹配。

答案 2 :(得分:-1)

执行((?<![a-zA-Z_])\d+(\.\d+)?)

之类的操作

它使用负面的lookbehind,以便在它之前不选择任何有[a-zA-Z_]的东西。 请在Regex101中查看。

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