![](/img/trans.png)
[英]reg ex to allow any combination of numbers till the specific number python
[英]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)。 将+
更改为*
会导致错误的匹配。
如果有人可以指出我的错误,那就太好了。
谢谢!
这实际上并不简单。 浮点文字比您想象的要复杂,它可以包含e
或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'
。 但是要区分这些并不容易,您应该考虑使用适当的公式解析器。
也许标准模块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
匹配。
尝试失败的主要原因是它以[^.*+=<>]
结尾,要求数字 (或更确切地说是match )以非字符结尾.
, *
, =
, +
, <
或>
。 并且当以0
和0.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.