我正在尝试一次执行一组搜索并替换文件。为此,我使用的是一个字典,其中要搜索的模式是键,替换文本是键值。我在一个模式中编译所有替换,然后使用下面的代码进行搜索替换:
re_compiled = re.compile("|".join(k for k in sub_dict))
# Pattern replacement inner function
def replacement_function(match_object):
key = str(match_object.group(0))
if key.startswith(r'C:\work\l10n'):
key = key.replace("\\", "\\\\")
key = key[:-1] + '.'
return sub_dict[key]
while 1:
lines = in_f.readlines(100000)
if not lines:
break
for line in lines:
line = re_compiled.sub(replacement_function, line)
out_f.write(line)
我按如下方式定义字典:
g_sub_dict = {
r'C:\\work\\l10n\\.' : r'/ae/l10n/'
, r'maxwidth="0"' : r'maxwidth="-1"'
, r'></target>' : r'>#####</target>'
}
我对第一个键(这是一个Windows路径,并使用反斜杠)感到头疼,主要是因为它被用作模式。
r'C:\\work\\l10n\\.'
我转义反斜杠,因为该字符串将用作模式。C:\\\\work\\\\l10n\\\\.
反斜杠出现双重转义,我理解,因为我将字符串定义为原始字符串。C:\\work\\l10n\\.
我完全看到我写的原始字符串。打印整个字典报告的字符串与打印单个字符串不同,这有点令人困惑,但我想这与“打印字典”的实现有关。'C:\work\l10n\.'
非转义反斜杠。C:\\work\\l10n\\.
这段代码能以某种方式简化吗?例如。所以我不需要通过代码逃避反斜杠?
答案 0 :(得分:2)
您可以尝试以下方式:
>>> text = r'start C:\work\l10n\. normal data maxwidth="0" something something ></target> end'
>>> # sub_dict format: {'symbolic_group_name': ['pattern', 'replacement']}
...
>>> sub_dict = {'win_path': [r'C:\\work\\l10n\\.', r'/ae/l10n//'],
... 'max_width': [r'maxwidth="0"', r'maxwidth="-1"'],
... 'target': [r'></target>', r'>#####</target>']}
>>> p = re.compile("|".join('(?P<{}>{})'.format(k, v[0]) for k, v in sub_dict.items()))
>>> def replacement_function(match_object):
... for group_name, match_value in match_object.groupdict().items():
... if match_value:
... # based on how the pattern is compiled 1 group will be a match
... # when we find it, we return the replacement text
... return sub_dict[group_name][1]
...
>>> new_text = p.sub(replacement_function, text)
>>> print(new_text)
start /ae/l10n// normal data maxwidth="-1" something something >#####</target> end
>>>
使用命名组,您可以依赖简单的字符串在替换词典中进行查找,而不需要对\
进行特殊处理。
编辑:
关于正则表达式模式的更改:我更改了a | b | c模式以使用命名组。命名捕获组的语法为(?P<name>pattern)
。在功能上它与pattern
相同,但是具有命名组允许使用组名从Matcher
对象获取数据(例如:matcher.group('name')
vs matcher.group(0)
)< / p>
groupdict
方法返回模式中的命名组及其匹配的值。因为模式是group1|group2|group3
,所以只有一个组实际上会匹配;其他2将在None
返回的dict中具有groupdict
值(在我的示例中:match_value
将是!=仅对于导致匹配的组而言是无)。
好处是组名可以是任何普通字符串(最好是简单的,与模式的目的相关),它不会导致\
转义问题。