首页 > 解决方案 > Python使用lookahead/lookbehind替换整个单词

问题描述

在正则表达式中使用向前看和向后看如何使用 python 成功替换以下单词而不替换其他看起来相似的单词。

css = '''
     selection-background-color: primary;
     selection-background-color:primary;
     selection-color: text-primary;
     selection-background-color: primary-text;
'''

我试图(?<!\w)primary(?=\w)根据我在网上研究的内容来使用它,但我对正则表达式和编写它的最佳方式并不十分熟悉。

我希望我从上面的代码中得到的结果可以创建这个......

css = css.replace('primary', 'rgb(255,255,255)')
css = css.replace('primary-text', 'red')
css = css.replace('text-primary', 'green')

返回:

css = '''
     selection-background-color: rgb(255,255,255);
     selection-background-color:rgb(255,255,255);
     selection-color: green;
     selection-background-color: red;
'''

标签: pythonregex

解决方案


通常,您会使用单词边界 ( \b) 来解决此类问题,但是因为您的单词可以作为多部分单词的一部分出现,其中部分由连字符分隔(与单词边界匹配),这将不起作用。相反,您可以为字符或单词周围的连字符匹配向前和向后的否定环视:

import re

css = '''
     selection-background-color: primary;
     selection-background-color:primary;
     selection-color: text-primary;
     selection-background-color: primary-text;
'''

css = re.sub(r'(?<![a-z-])primary(?![a-z-])', 'rgb(255,255,255)', css)
css = re.sub(r'(?<![a-z-])primary-text(?![a-z-])', 'red', css)
css = re.sub(r'(?<![a-z-])text-primary(?![a-z-])', 'green', css)
        
print(css)

输出:

selection-background-color: rgb(255,255,255);
selection-background-color:rgb(255,255,255);
selection-color: green;
selection-background-color: red;

您还可以尝试基于字典的方法,从字典的键中生成正则表达式并替换为匹配的值:

replacements = {
    'primary' : 'rgb(255,255,255)',
    'primary-text' : 'red',
    'text-primary' : 'green'
}
regex = '(?<![a-z-])(?:' + '|'.join(replacements.keys()) + ')(?![a-z-])'

css = re.sub(regex, lambda m: replacements[m.group()], css)

print(css)

推荐阅读