使用正则表达式拆分字符串并对其进行评估

时间:2017-08-01 14:25:39

标签: python regex string

我有一个包含一些变量,算术和逻辑运算符的字符串。我的问题陈述是替换变量的值并对其进行评估并发送True或False

我的字符串:

'ABC >= 55 and Xyz <= 5500 or ABCDe == 900 or xYz == 30'

在这里,ABC,Xyz和ABCDe是动态的,它可以是任何东西。我需要从str1获取这些变量的值,并在下面进行评估

eval( 100 >= 55 and 555 <= 5500 or 50 == 900 or 10 == 30)

我尝试了以下事项,

def replace(match):
    return '{}'.format(10)

re.sub(r'[a-b|A-Z]\w+',replace, str1)

输出:

'10 >= 55 10 10 <= 5500 or 10 == 900 or x10 == 30'

问题在于它取代&#39;和&#39;,&#39;或&#39;也替换不合适它取代xYz as x10 然后我尝试用特殊字符替换那些

>> str2 = str1.replace('and', '&').replace('or', '|')

>> print str2
>> ABC >= 55 & Xyz <= 5500 | ABCDe == 900 | xYz == 30

>> re.sub(r'[a-b|A-Z]\w+',replace, str2)

它解决了操作符的替换而不是区分大小写的问题

'10 >= 55 & 10 <= 5500 | 10 == 900 | x10 == 30'

有人可以帮助我......或者其他任何方式吗?

3 个答案:

答案 0 :(得分:1)

我看到的一个问题是你的替换函数总是返回10:

return '{}'.format(10) 

将始终返回10,这就是你的字符串不正确的原因。

我看到的另一件事是你没有指出哪个值属于哪个动态变量。

我能够通过以下代码解决问题:(快速粗暴地输入)

import re

rep_hash = {
    r'ABC\b' : '100',
    r'Xyz\b' : '555',
    r'ABCDe\b' : '50',
    r'xYz\b' : '10'
}

str1 = 'ABC >= 55 and Xyz <= 5500 or ABCDe == 900 or xYz == 30'
str2 = ''
for item in rep_hash:
    str1 = re.sub(item, rep_hash[item], str1)

print str1

\ b使它完全匹配,以便ABC不匹配ABCDe

答案 1 :(得分:1)

my_string = 'ABC >= 55 and Xyz <= 5500 or ABCDe == 900 or xYz == 30'开始。我假设这个字符串应该是一个有效的Python表达式。

我假设你有一个名为variable_values的字典:

variable_values = {'ABC': 10, 'Xyz': 555, 'ABCDe': 50, 'xYz': 10} 

你必须拥有某种东西,否则你就不知道要替代什么。

步骤1.替换变量名称的值。您只能使用string.replace()来执行此操作,因为如果您有两个变量ABCABCABC,而ABC的值为100,那么做一个天真的替换将替换100100的值ABCABC,这可能是不正确的。所以要坚持变量名必须以word_boundary开头和结尾。

for name, value in variable_values.items():
    my_string = re.sub(fr"\b{name}\b",str(value),my_string)

步骤2.现在my_string的值为'10 >= 55 and 555 <= 5500 or 50 == 900 or 10 == 30'。点击eval()就可以了。

>>> eval(my_string)
False

答案 2 :(得分:0)

以某种方式让它在下面工作。

def replace(match):
    return '{}'.format(10)

my_string = 'ABC >= 55 and Xyz <= 5500 or ABCDe == 900 or xYz == 30'

string2 = my_string.replace('and', '&').replace('or', '|')

eval(re.sub(r'[a-zA-Z]\w+\b',replace, string2))
# False

有没有更好更有效的方法呢