长话短说,我有两个正则表达式.一种模式匹配我想要替换的内容,另一种模式匹配那些不应替换的模式的特殊情况.举一个简单的例子,假设第一个是"\ {.*\}",第二个是"\ {\ {.*\} \}".然后应该替换"{this}",但不应该"{{this}}".是否有一种简单的方法来取一个字符串并说"用"hello"替换第一个字符串的所有实例,只要它不匹配第二个字符串"?
换句话说,有没有办法在不修改第一个字符串的情况下轻松制作"匹配第一个字符串而不是第二个字符串"的正则表达式?我知道我可以手动修改我的第一个正则表达式,从不匹配第二个正则表达式的实例,但是随着第一个正则表达式变得更加复杂,这变得非常困难.
使用负前瞻/后方断言
pattern = re.compile( "(?<!\{)\{(?!\{).*?(?<!\})\}(?!\})" )
pattern.sub( "hello", input_string )
Run Code Online (Sandbox Code Playgroud)
负向前瞻/后方断言允许您与更多字符串进行比较,但不会将其视为用尽匹配的字符串的一部分.还有一个正常的前面/后面断言,只有当字符串IS跟随/前面给定的模式时才会使字符串匹配.
这看起来有点令人困惑,在这里它是碎片:
"(?<!\{)" #Not preceded by a {
"\{" #A {
"(?!\{)" #Not followed by a {
".*?" #Any character(s) (non-greedy)
"(?<!\})" #Not preceded by a } (in reference to the next character)
"\}" #A }
"(?!\})" #Not followed by a }
Run Code Online (Sandbox Code Playgroud)
所以,我们正在寻找一个{没有任何其他的',其次是一些字符,然后是},而没有任何其他}围绕它.
通过使用负向前瞻/后方断言,我们将其压缩为单个正则表达式,该表达式将成功匹配字符串中任何位置的单个{}.
另外,请注意*是一个贪婪的运算符.它将尽可能多地匹配.如果您使用"\{.*\}"并且文本中有多个{}块,则将使用它之间的所有内容.
"这是一些示例文本{block1}更多文字,看着我消失{block2}更多文字"
变
"这是一些示例文本你好更多的文字"
代替
"这是一些示例文本你好更多的文字,看着我消失你好更多的文字"
为了获得正确的输出,我们需要通过附加?来使其变得非贪婪.
python文档可以很好地呈现re库,但真正学习的唯一方法是进行实验.
你可以给replace一个函数(参考)
但请确保第一个正则表达式包含第二个正则表达式。这只是一个例子:
regex1 = re.compile('\{.*\}')
regex2 = re.compile('\{\{.*\}\}')
def replace(match):
match = match.group(0)
if regex2.match(match):
return match
return 'replacement'
regex1.sub(replace, data)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1265 次 |
| 最近记录: |