1

回到这个例子,

在 Python 中使用正则表达式处理类似字符以打印不同内容时遇到问题

我想知道如何反转我所做的正则表达式替换并打印出原始文本?

也就是说,所以如果我有

text = "This is my first regex python example yahooa yahoouuee bbbiirdd"

作为我的原始文本,那么它的输出将是:

re.sub text = "tookhookisook isook mookyook fookirooksooktook pookyooktookhookonook..."

然后我希望将该输出转换回原始文本。

我怎么做?

4

3 回答 3

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(),结果是一个的字符串,而原来的字符串是不变的。

>>> s.replace ('a', 'd')
'dbc'
>>> s
'abc'
>>> 
于 2013-03-03T17:39:31.973 回答
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'替换一个字母,而是根据字母替换。
例如,我选择将 'b' 替换为 'BAR',将 'c' 替换为 'CORE'.... 我将字典的值大写,以便更好地查看结果。它实际上可能是其他任何东西。
这些程序会处理这种情况。我在字典里只放了'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
于 2013-03-03T20:34:41.847 回答
0

您不能在 Python 或任何其他正则表达式实现中向后“转换”正则表达式替换。

那只是因为替换是返回一个新字符串的单向街道,并且没有神奇的反转功能

这是使用 string.replace() 的插图:

original_string = 'abc'
newstring = original_string.replace('a','b')
'bbc'

将 newstring 转换为 'abc' 不仅仅是用 'b' 代替 'a'。您不能从任何给定的正则表达式中创建“反向”正则表达式。如果我们在本例中将“b”替换为“a”,则字符串将是“aac”——而不是 bbc。

正则表达式函数的工作方式与 string.replace 相同——它们返回一个新字符串。他们不会返回一个知道每个正则表达式替换的确切状态的对象。

您有两种选择可以做任何您想做的事情:

1-创建一个表示字符串并跟踪(无限?)数量的正则表达式操作的自定义类,允许您在每个状态之间创建差异。

2-做其他人所做的事情,以及这里许多人的建议:您只需将原始字符串(或它的副本)放在一边。

(这是为了简化@StoryTeller 的答案)

于 2013-03-03T20:47:57.230 回答