Using look ahead and look behind in regex how can i replace the following words succefully using python without replacing other words that appear similar.
css = '''
selection-background-color: primary;
selection-background-color:primary;
selection-color: text-primary;
selection-background-color: primary-text;
'''
I was trying to use this (?<?\w)primary(?=\w)
based on what I was researching online but I'm not super familiar with regex and the best way to write this.
I would expect my results from the code above to create this...
css = css.replace('primary', 'rgb(255,255,255)')
css = css.replace('primary-text', 'red')
css = css.replace('text-primary', 'green')
returns:
css = '''
selection-background-color: rgb(255,255,255);
selection-background-color:rgb(255,255,255);
selection-color: green;
selection-background-color: red;
'''
Normally you would use word boundaries ( \b
) to resolve this type of problem, however because your words can appear as part of a multi-part word with the parts separated by a hyphen (which matches a word boundary) this won't work. Instead, you can match with forward and backward negative lookarounds for a character or a hyphen around the word:
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)
Output:
selection-background-color: rgb(255,255,255);
selection-background-color:rgb(255,255,255);
selection-color: green;
selection-background-color: red;
You can also try a dictionary-based approach, making a regex out of the keys of the dictionary and replacing with the matching value:
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)
Since all your replacements are on values in colon-delimited key-value pairs, you can instead use a dict that maps values to their replacements and use re.sub
with a regex that groups the values and the characters before them to replace the matches with a function that returns the values replaced by the mapped replacements if they are in the mapping table:
mapping = {
'primary': 'rgb(255,255,255)',
'primary-text': 'red',
'text-primary': 'green'
}
css = re.sub(
r'(:\s*)(.*);',
lambda m: m.group(1) + mapping.get(m.group(2), m.group(2)),
css
)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.