回到这个例子,
Having trouble dealing with similar characters to print different things using regex in Python
我想知道如何改变我所做的正则表达式替换并打印出原始文本?
就是这样,如果我有
text = "This is my first regex python example yahooa yahoouuee bbbiirdd"
作为我的原始文本,然后它的输出将是:
re.sub text = "tookhookisook isook mookyook fookirooksooktook pookyooktookhookonook..."
然后我希望将输出转换回原始文本。
我该怎么做?
答案 0 :(得分:4)
Python字符串是不可变的。您还没有更改原始文件,只创建了一个新字符串。只需保留对原文的引用。
修改强>
通过不可变,我的意思是它们的实际值在创建后被冻结。
>>> s = "abc"
>>> s[0]
'a'
>>> s[1] = 'd'
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
s[1] = 'd'
TypeError: 'str' object does not support item assignment
>>>
在上面的例子中,我可以让变量s
引用另一个对象,但我赋给它的字符串是常量。因此,当您执行s.replace()
时,结果是 new 字符串,并且原始字符串保持不变。
>>> s.replace ('a', 'd')
'dbc'
>>> s
'abc'
>>>
答案 1 :(得分:1)
这似乎有效:
import re
tu = ('This is my first regex python example '
'yahooa yahoouuee bbbiirdd',
'bbbiirdd',
'fookirooksooktook',
'crrsciencezxxxxxscienceokjjsciencq')
reg = re.compile(r'([bcdfghj-np-tv-z])(\1?)')
dereg = re.compile('science([^aeiou])|([^aeiou])ook')
def Frepl(ma):
g1,g2 = ma.groups()
if g2: return 'science' + g2
else: return g1 + 'ook'
def Fderepl(ma):
g = ma.group(2)
if g: return g
else: return 2*ma.group(1)
for strt in tu:
resu = reg.sub(Frepl , strt)
bakk = dereg.sub(Fderepl, resu)
print ('----------------------------------\n'
'strt = %s\n' 'resu == %s\n'
'bakk == %s\n' 'bakk == start : %s'
% (strt, resu, bakk, bakk==strt))
首先,我更新了上面的代码:我删除了re.I
标志。它正在捕捉像'dD'这样的重复字母。所以它被转换为'scienceD',然后回到'DD'
其次,我用字典扩展了代码 它不是用字母+'ook'替换字母,而是根据字母替换 例如,我选择用'BAR'替换'b',用'CORE'替换'c'....我把字典的值大写,以便更好地查看结果。实际上它可能是其他任何东西 程序负责处理此案。我在字典中只放了'T','Y','X',这只是为了文章。
import re
d = {'b':'BAR','c':'CORE','d':'DEAD','f':'FAN',
'g':'GO','h':'HHH','j':'JIU','k':'KOAN',
'l':'LOW','m':'MY','n':'NERD','p':'PI',
'q':'QIM','r':'ROAR','s':'SING','t':'TIP',
'v':'VIEW','w':'WAVE','x':'XOR',
'y':'YEAR','z':'ZOO',
'T':'tears','Y':'yearling','X':'xylophone'}
ded = dict((v,k) for k,v in d.iteritems())
print ded
tu = ('This is my first regex python example '
'Yahooa yahoouuee bbbiirdd',
'bbbiirdd',
'fookirooksooktook',
'crrsciencezxxxxxXscienceokjjsciencq')
reg = re.compile(r'([bcdfghj-np-tv-zBCDFGHJ-NP-TV-Z])(\1?)')
othergr = '|'.join(ded.keys())
dereg = re.compile('science([^aeiouAEIOU])|(%s)' % othergr)
def Frepl(ma, d=d):
g1,g2 = ma.groups()
if g2: return 'science' + g2
else: return d[g1]
def Fderepl(ma,ded=ded):
g = ma.group(2)
if g: return ded[g]
else: return 2*ma.group(1)
for strt in tu:
resu = reg.sub(Frepl , strt)
bakk = dereg.sub(Fderepl, resu)
print ('----------------------------------\n'
'strt = %s\n' 'resu == %s\n'
'bakk == %s\n' 'bakk == start : %s'
% (strt, resu, bakk, bakk==strt))
结果
----------------------------------
strt = This is my first regex python example Yahooa yahoouuee bbbiirdd
resu == tearsHHHiSING iSING MYYEAR FANiROARSINGTIP ROAReGOeXOR PIYEARTIPHHHoNERD eXORaMYPILOWe yearlingaHHHooa YEARaHHHoouuee sciencebBARiiROARscienced
bakk == This is my first regex python example Yahooa yahoouuee bbbiirdd
bakk == start : True
----------------------------------
strt = bbbiirdd
resu == sciencebBARiiROARscienced
bakk == bbbiirdd
bakk == start : True
----------------------------------
strt = fookirooksooktook
resu == FANooKOANiROARooKOANSINGooKOANTIPooKOAN
bakk == fookirooksooktook
bakk == start : True
----------------------------------
strt = crrsciencezxxxxxXscienceokjjsciencq
resu == COREsciencerSINGCOREieNERDCOREeZOOsciencexsciencexXORxylophoneSINGCOREieNERDCOREeoKOANsciencejSINGCOREieNERDCOREQIM
bakk == crrsciencezxxxxxXscienceokjjsciencq
bakk == start : True
答案 2 :(得分:0)
您无法在Python或任何其他正则表达式实现中向后“转换”正则表达式替换。
这只是因为替换是一条返回新字符串的单行道,并且没有神奇的反转功能
以下是使用string.replace():
的插图original_string = 'abc'
newstring = original_string.replace('a','b')
'bbc'
将newstring转换为'abc'不仅仅是将'b'替换为'a'。你不能在任何给定的正则表达式中创建一个“反向”正则表达式。如果我们在这个例子中用'a'替换'b',那么字符串将是'aac' - 而不是bbc。
正则表达式函数的工作原理与string.replace相同 - 它们返回一个新字符串。它们不会返回一个知道每个正则表达式替换的确切状态的对象。
你有两个选择可以做你想做的事情:
1-创建一个表示字符串并跟踪(无限?)个正则表达式操作的自定义类,允许您在每个状态之间创建差异。
2-做其他人做的事情,这里有很多人建议:你只需将原始字符串(或其副本)存放到一边。
(这是为了简化@StoryTeller的答案)