Python - 从字符串中读取标记

时间:2017-12-21 16:46:35

标签: python regex python-3.x

我正在从字符串中读取所有标记(运算符,intstr等)

我目前的代码:

import re
expression = "($mat.name == 'sign') AND ($most == 100.0)"
tokens = re.findall("\$+[a-zA-Z]*\.[a-zA-Z]+|[a-zA-Z]+|Not|not|NOT|[=]+|[+/*()-]|[0-9]*\.[0-9]+|[0-9]+", expression)

目前的结果:

['(', '$mat.name', '==', 'sign', ')', 'AND', '(', 'most', '==', '100.0', ')']

问题是,虽然正则表达式正确匹配$mat.name,但它匹配most而不是$most

你能帮我修一下正则表达式吗?

4 个答案:

答案 0 :(得分:1)

我不确定您要完成的是什么,但是您要匹配most代替$most,因为它不包含点并且您的表达与\$+[a-zA-Z]*\.[a-zA-Z]+[a-zA-Z]+匹配,显然$most字符串不包含.,因此它会尝试下一场比赛。

代码

See regex in use here

\$*(?:[a-z]*\.)?[a-z]+|not|[+/*()-]|\d*\.\d+|[\d=]+

注意:以上正则表达式简化了原始正则表达式,并与i标志一起使用(忽略大小写)

用法

See code in use here

import re
expression = "($mat.name == 'sign') AND ($most == 100.0)"
tokens = re.findall(r"\$*(?:[a-z]*\.)?[a-z]+|not|[+/*()-]|\d*\.\d+|[\d=]+", expression, re.I)

print tokens

结果

输入

($mat.name == 'sign') AND ($most == 100.0)

输出

['(', '$mat.name', '==', 'sign', ')', 'AND', '(', '$most', '==', '100.0', ')']

说明

我对你的模式做了一些其他修改,所以我会解释整个事情。

  • 匹配以下任何一项
    • \$+(?:[a-z]*\.)?[a-z]+符合以下条件
      • \$*多次匹配$
      • (?:[a-z]*\.)?匹配以下零次或一次
        • [a-z]*匹配任意数量的小写ASCII字母
        • \.匹配文字点字符.
      • [a-z]+匹配一个或多个小写ASCII字母
    • not按字面意思匹配
    • [+/*()-]匹配集合中的任何字符
    • \d*\.\d+符合以下条件
      • \d*匹配任意位数
      • \.匹配文字点字符.
      • \d+匹配一个或多个数字
    • [\d=]+匹配集合中的任何字符(数字或=)一次或多次

答案 1 :(得分:0)

您应该使用以下修改过的正则表达式。

import re
expression = "($mat.name == 'sign') AND ($most == 100.0)"
tokens = re.findall("\$+[a-zA-Z]*\.[a-zA-Z]+|\$+[a-zA-Z]*|[a-zA-Z]+|Not|not|NOT|[=]+|[+/*()-]|[0-9]*\.[0-9]+|[0-9]+", expression)
print(tokens)

将打印

['(', '$mat.name', '==', 'sign', ')', 'AND', '(', '$most', '==', '100.0', ')']

查看修改后的正则表达式here的完整说明。

答案 2 :(得分:-1)

您只接受以$开头的字符串:

\$+[a-zA-Z]*\.[a-zA-Z]+

$最大的避风港点,所以你必须改变它,并采取没有点的字符串

\$+[a-zA-Z]*(\.[a-zA-Z]+)?

答案 3 :(得分:-1)

在您的第二个令牌中,您必须检查.是否存在,因为.在每个变量中都不是强制性的!

>>> re.findall("\$+[a-zA-Z]*\.?[a-zA-Z]+|[a-zA-Z]+|Not|not|NOT|[=]+|[+/*()-]|[0-9]*\.[0-9]+|[0-9]+", expression)
['(', '$mat.name', '==', 'sign', ')', 'AND', '(', '$most', '==', '100.0', ')']

类似的解决方案如下(简化有问题的正则表达式) -

>>> re.findall('\$+[A-Z.a-z]+|[a-zA-Z]+|Not|not|NOT|=+|[+/*()-]|[0-9.]+', expression)
['(', '$mat.name', '==', 'sign', ')', 'AND', '(', '$most', '==', '100.0', ')']