我正在从字符串中读取所有标记(运算符,int
,str
等)
我目前的代码:
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
。
你能帮我修一下正则表达式吗?
答案 0 :(得分:1)
我不确定您要完成的是什么,但是您要匹配most
代替$most
,因为它不包含点并且您的表达与\$+[a-zA-Z]*\.[a-zA-Z]+
或[a-zA-Z]+
匹配,显然$most
字符串不包含.
,因此它会尝试下一场比赛。
\$*(?:[a-z]*\.)?[a-z]+|not|[+/*()-]|\d*\.\d+|[\d=]+
注意:以上正则表达式简化了原始正则表达式,并与i
标志一起使用(忽略大小写)
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', ')']