Regex replacement
I have a string like this one:
{{foobar
| option1 = foo
| option2 = foo
| <!-- more options -->开发者_StackOverflow中文版
| something = xxx
| thisoption = xxx
| <!-- more options -->
}}
I want it to be "thisoption = xxx" to be replaced by "thisoption = abc". It shouldn't matchany of the following:
{{foobar
| option1 = foo
| option2 = foo
| thisoption = xyz
}}
{{foobar
| option1 = foo
| option2 = foo
}}
{{someotherthing
| thisoption = xxx
}}
How can I do this?
The question is a little vague, but try this:
re.sub(r'(?P<name>foobar[^}]* = xxx\b)', r'\g<name>2', string)
It looks for a match for foobar
and a match for xxx
without any closing braces in between, i.e. xxx
is in foobar
.
>>> string = '{{foobar\n| option1 = foo\n| option2 = foo\n| <!-- more options -->\n| thisoption = xxx\n| <!-- more options -->\n}}'
>>> re.sub(r'(?P<name>foobar[^\}]*xxx)', r'\g<name>2', string)
'{{foobar\n| option1 = foo\n| option2 = foo\n| <!-- more options -->\n| thisoption = xxx2\n| <!-- more options -->\n}}'
Your first test case; in this case xxx is replaced by xxx2.
>>> string = '{{foobar\n| option1 = foo\n| option2 = foo\n| thisoption = xyz\n}}'
>>> re.sub(r'(?P<name>foobar[^\}]*xxx)', r'\g<name>2', string)
'{{foobar\n| option1 = foo\n| option2 = foo\n| thisoption = xyz\n}}'
Second test case; nothing happens.
>>> string = '{{foobar\n| option1 = foo\n| option2 = foo\n}}\n{{someotherthing\n| thisoption = xxx\n}}'
>>> re.sub(r'(?P<name>foobar[^\}]*xxx)', r'\g<name>2', string)
'{{foobar\n| option1 = foo\n| option2 = foo\n}}\n{{someotherthing\n| thisoption = xxx\n}}'
Third test case; again nothing happens.
Hope this helps!
To answer my own question, this seemed to do the trick:
re.sub(r"(\{\{foobar[^\}]*)thisoption ?= ?xxx", r"\1thisoption = abc", string)
Thanks to everyone who helped out!
Your example looks kind of like an INI settings file, just with a different syntax. You should check out python's ConfigParser module, it already handles all this.
import re
ss = '''{{foobar
| option1 = foo
| option2 = foo
| <!-- more options -->
| something = xxx
| thisoption = xxx
| <!-- more options -->
}}'''
tt = '''{{foobar
| option1 = foo
| option2 = foo
| thisoption = xyz
}}'''
uu = '''{{foobar
| option1 = foo
| option2 = foo
}}
{{someotherthing
| thisoption = xxx
}}'''
regx = re.compile('(\{\{foobar *\r?\n'
'([^}]*\r?\n)+?'
'\| thisoption *= *)(xxx)')
for x in (ss,tt,uu,vv,zz):
print regx.sub('\\1abcd',x)
print
print re.sub(r'(?P<name>foobar[^\}]*xxx)', r'\g<name>2', x)
print '\n-----------------------------------------------------------'
result
{{foobar
| option1 = foo
| option2 = foo
| <!-- more options -->
| something = xxx
| thisoption = abcd
| <!-- more options -->
}}
{{foobar
| option1 = foo
| option2 = foo
| <!-- more options -->
| something = xxx
| thisoption = xxx2
| <!-- more options -->
}}
-----------------------------------------------------------
{{foobar
| option1 = foo
| option2 = foo
| thisoption = xyz
}}
{{foobar
| option1 = foo
| option2 = foo
| thisoption = xyz
}}
-----------------------------------------------------------
{{foobar
| option1 = foo
| option2 = foo
}}
{{someotherthing
| thisoption = xxx
}}
{{foobar
| option1 = foo
| option2 = foo
}}
{{someotherthing
| thisoption = xxx
}}
-----------------------------------------------------------
The solution of discipulus , as I see it presently, doesn't work in the following cases:
vv = '''{{foobar
| option1 = foo
| option2 = foo
| thisoption = xxx
| last_xxxxx_option = toxic
}}'''
zz = '''{{foobar
| option1 = foo
| option2 = foo
| thisoption = xxx
| last_option = toxxxic
}}'''
for which:
{{foobar
| option1 = foo
| option2 = foo
| thisoption = abcd
| last_xxxxx_option = toxic
}}
{{foobar
| option1 = foo
| option2 = foo
| thisoption = xxx
| last_xxxxx2_option = toxic
}}
-----------------------------------------------------------
{{foobar
| option1 = foo
| option2 = foo
| thisoption = abcd
| last_option = toxxxic
}}
{{foobar
| option1 = foo
| option2 = foo
| thisoption = xxx
| last_option = toxxx2ic
}}
-----------------------------------------------------------
精彩评论