首先,我们可以通过对字符串使用单引号来简化您的正则表达式。这消除了转义"
字符的必要性。其次,{0,1}
可以替换为?
:
raw = r'(?P<type>^.)(?:"(?P<prefix>[^"]*)")?(?P<format>[^"]*)(?:"(?P<suffix>[^"]*)")?;(?P<negformat>.)(?:"(?P<prefix2>(?P=prefix))")?(?P=format)(?:"(?P<suffix2>(?P=suffix))")?'
请注意,我在上面添加了(?P<prefix2>)
和(?P<suffix2)
命名组,用于第二次出现的前缀和后缀。
我正在假设您的模式可以在文本中重复(如果模式仅出现一次,则此代码仍将起作用)。在那种情况下,必须从最后出现到第一次出现字符替换,以便即使进行字符替换后,由正则表达式引擎返回的start
和last
字符偏移信息也保持正确。同样,当我们发现模式出现时,必须首先按suffix2
,prefix2
,suffix
和prefix
的顺序进行替换。
我们使用re.finditer
遍历文本以返回match
对象并将它们形成为list
,我们将其反转以使我们可以首先处理最后的匹配项:
import re
raw = r'(?P<type>^.)(?:"(?P<prefix>[^"]*)")?(?P<format>[^"]*)(?:"(?P<suffix>[^"]*)")?;(?P<negformat>.)(?:"(?P<prefix2>(?P=prefix))")?(?P=format)(?:"(?P<suffix2>(?P=suffix))")?'
s = """a"prefix"format"suffix";b"prefix"format"suffix"
x"prefix_2"format_2"suffix_2";y"prefix_2"format_2"suffix_2"
"""
new_string = s
matches = list(re.finditer(raw,s,flags=re.MULTILINE))
matches.reverse()
if matches:
for match in matches:
if match.group('suffix2'):
new_string = new_string[0:match.start('suffix2')] + 'new_suffix' + new_string[match.end('suffix2'):]
if match.group('prefix2'):
new_string = new_string[0:match.start('prefix2')] + 'new_prefix' + new_string[match.end('prefix2'):]
if match.group('suffix'):
new_string = new_string[0:match.start('suffix')] + 'new_suffix' + new_string[match.end('suffix'):]
if match.group('prefix'):
new_string = new_string[0:match.start('prefix')] + 'new_prefix' + new_string[match.end('prefix'):]
print(new_string)
打印:
a"new_prefix"format"new_suffix";b"new_prefix"format"new_suffix"
x"new_prefix"format_2"new_suffix";y"new_prefix"format_2"new_suffix"
出于演示目的,以上代码对每次出现的模式进行了相同的替换。
第二点担心:
没有什么可以阻止您对文本进行两次传递,一次是替换前缀,一次是替换后缀,因为这些众所周知。显然,您只需要为每次通过检查某些组,但是您仍可以使用相同的正则表达式。当然,对于模式的每次出现,您都可以进行唯一的替换。上面的代码显示了如何查找和进行替换。
允许0到9个实例或前缀
import re
raw = r'(?P<type>^.)(?:"(?P<prefix>[^"]*)")?(?P<format>[^"]*)(?:"(?P<suffix>[^"]*)")?;(?P<negformat>.)(?P<prefix2>(?:"(?P=prefix)"){0,9})(?P=format)(?:"(?P<suffix2>(?P=suffix))")?'
s = """a"prefix"format"suffix";b"prefix""prefix""prefix"format"suffix"
x"prefix_2"format_2"suffix_2";y"prefix_2"format_2"suffix_2"
"""
new_string = s
matches = list(re.finditer(raw,flags=re.MULTILINE))
matches.reverse()
if matches:
for match in matches:
if match.group('suffix2'):
new_string = new_string[0:match.start('suffix2')] + 'new_suffix' + new_string[match.end('suffix2'):]
if match.group('prefix2'):
start = match.start('prefix2')
end = match.end('prefix2')
repl = s[start:end]
n = repl.count('"') // 2
new_string = new_string[0:start] + (n * '"new_prefix"') + new_string[end:]
if match.group('suffix'):
new_string = new_string[0:match.start('suffix')] + 'new_suffix' + new_string[match.end('suffix'):]
if match.group('prefix'):
new_string = new_string[0:match.start('prefix')] + 'new_prefix' + new_string[match.end('prefix'):]
print(new_string)
打印:
a"new_prefix"format"new_suffix";b"new_prefix""new_prefix""new_prefix"format"new_suffix"
x"new_prefix"format_2"new_suffix";y"new_prefix"format_2"new_suffix"
本文链接:https://www.f2er.com/3167190.html