我对python很新,所以我有一个包含一些键的字典和一个字符串。如果在字典中存在字典中存在的模式,我必须替换字符串。字典和字符串都非常大。我正在使用正则表达式来查找模式。
一切正常,直到像这样的键弹出' - ('或''( - )',在这种情况下,python会给不平衡的括号带来错误。
以下是我编写的代码的外观:
somedict={'-(':'value1','(-)':'value2'}
somedata='this is some data containing -( and (-)'
for key in somedict.iterkeys():
somedata=re.sub(key, 'newvalue', somedata)
这是我在控制台中遇到的错误
Traceback (most recent call last):
File "<console>", line 2, in <module>
File "C:\Python27\lib\re.py", line 151, in sub
return _compile(pattern, flags).sub(repl, string, count)
File "C:\Python27\lib\re.py", line 244, in _compile
raise error, v # invalid expression
error: unbalanced parenthesis
我也尝试了很多方法使用正则表达式编译器并搜索了很多但没有找到任何解决问题的方法。任何帮助表示赞赏。
答案 0 :(得分:8)
您需要使用re.escape()
逃避密钥:
somedata = re.sub(re.escape(key), 'newvalue', somedata)
否则内容将被解释为正则表达式。
你根本就没有使用正则表达式,所以你也可以使用:
somedata = somedata.replace(key, 'newvalue')
如果你只想替换整个单词(所以在它们周围有空格或标点符号,在输入字符串的开头或结尾),你需要某种边界锚点,指出使用正则表达式是有意义的。如果你只有字母数字(加上下划线),那么\b
就可以了:
somedata = re.sub(r'\b{}\b'.format(re.escape(key)), 'newvalue', somedata)
这会在您要替换的字符串之前和之后放置\b
,以便更改baz
中的foo baz bar
,但foo bazbaz bar
不是。
对于涉及非字母数字“单词”的输入,您需要将whitespace-or-start和whitespace-or-end锚点与前瞻和后视匹配:
somedata = re.sub(r'(?:^|(?<=\s)){}(?:$|(?=\s))'.format(re.escape(key)), 'newvalue', somedata)
此处模式(?:^|(?<=\s))
使用两个锚点,字符串开始锚点和后面的断言,以匹配字符串开头或者字符串的位置或一个紧靠左边的空间。类似地,(?:$|(?=\s)
对另一端做同样的事情,匹配字符串的末尾或后跟空格的位置。
答案 1 :(得分:1)
不要将re
用于这么简单的事情 - 只需替换:
somedata = somedata.replace(key, 'newvalue')
也就是说,如果你正在构建一个正则表达式,请使用re.escape
来转义特殊字符:
somedata=re.sub(re.escape(key), 'newvalue', somedata)