我很难理解你的算法的原理,因为我不习惯使用指定的组。
下面的代码是我会解决你的问题的方式,我希望它会给你一些想法。
我认为只有一个字典不是一个好原则,它增加了推理和算法的复杂性。因此,我将代码基于两个字典:direg和内存
这两个字典的键是索引的组,而不是所有的索引,只有一些特定的索引,组的索引是每个单独模式中的最后一个。
因为,为了好玩,我决定正则表达式必须能够有几个组。
我称之为个人模式在我的代码是以下字符串:
"[mM]y name [Ii][sS] (\w*)"
"[Ii]n repertory (\w*) I [wW][aA][nN][tT] file (\w*)"
"[Ii] [wW][aA][nN][tT] to ([ \w]*)"
您将看到第二个人模式有2个捕获组:因此有3种个人模式,但在总共4组所有的个人群体。
所以字典的创建需要一些额外的照顾考虑到一个事实,即最后一个匹配组的索引(我用的名字的属性的帮助下使用lastIndex的正则表达式MatchObject的)可能不对应到正则表达式中存在的单个正则表达式的编号:解释比理解更难。这就是为什么我计算函数distr()字符串{0} {1} {2} {3} {4}等的发生次数等其编号必须与在相应的个人模式。
我找到了Laurence D'Oliveiro建议使用'||'而不是'|'作为分隔符有趣。
我的代码模拟在几个输入端完成会话: “Talk是便宜给我的代码。”
import re
regi = ("[mM]y name [Ii][sS] (\w*)"
"||Hi {0}!"
"||You said that your name was {0} !!!",
"[Ii]n repertory (\w*) I [wW][aA][nN][tT] file (\w*)"
"||OK here's your file {0}\\{1} :"
"||I already gave you the file {0}\\{1} !",
"[Ii] [wW][aA][nN][tT] to ([ \w]*)"
"||OK, I will do {0}"
"||You already did {0}. Do yo really want again ?")
direg = {}
memory = {}
def distr(regi,cnt = 0,di = direg,mem = memory,
regnb = re.compile('{\d+}')):
for i,el in enumerate(regi,start=1):
sp = el.split('||')
cnt += len(regnb.findall(sp[1]))
di[cnt] = sp[1]
mem[cnt] = sp[2]
yield sp[0]
regx = re.compile('|'.join(distr(regi)))
print 'direg :\n',direg
print
print 'memory :\n',memory
for inp in ('I say that my name is Armano the 1st',
'In repertory ONE I want file SPACE',
'I want to record music',
'In repertory ONE I want file SPACE',
'I say that my name is Armstrong',
'But my name IS Armstrong now !!!',
'In repertory TWO I want file EARTH',
'Now my name is Helena'):
print '\ninput ==',inp
mat = regx.search(inp)
if direg[mat.lastindex]:
print 'output ==',direg[mat.lastindex]\
.format(*(d for d in mat.groups() if d))
direg[mat.lastindex] = None
memory[mat.lastindex] = memory[mat.lastindex]\
.format(*(d for d in mat.groups() if d))
else:
print 'output ==',memory[mat.lastindex]\
.format(*(d for d in mat.groups() if d))
if not memory[mat.lastindex].startswith('Sorry'):
memory[mat.lastindex] = 'Sorry, ' \
+ memory[mat.lastindex][0].lower()\
+ memory[mat.lastindex][1:]
结果
direg :
{1: 'Hi {0}!', 3: "OK here's your file {0}\\{1} :", 4: 'OK, I will do {0}'}
memory :
{1: 'You said that your name was {0} !!!', 3: 'I already gave you the file {0}\\{1} !', 4: 'You already did {0}. Do yo really want again ?'}
input == I say that my name is Armano the 1st
output == Hi Armano!
input == In repertory ONE I want file SPACE
output == OK here's your file ONE\SPACE :
input == I want to record music
output == OK, I will do record music
input == In repertory ONE I want file SPACE
output == I already gave you the file ONE\SPACE !
input == I say that my name is Armstrong
output == You said that your name was Armano !!!
input == But my name IS Armstrong now !!!
output == Sorry, you said that your name was Armano !!!
input == In repertory TWO I want file EARTH
output == Sorry, i already gave you the file ONE\SPACE !
input == Now my name is Helena
output == Sorry, you said that your name was Armano !!!
- Linus Torvalds。另请参阅[常见问题](http://stackoverflow.com/faq)。 – PointedEars 2012-02-07 10:12:52
@ user1189336在定义名称_string_的对象的表达式中,'word'**的用途是什么? – eyquem 2012-02-07 11:56:10
@eyquem这样做的目的是修复一个错误,即如果用户在输入结束时没有再输入另一个单词,程序将默认为'else'选项。不过,我现在认识到最好简单地将行分割为'|'而不是'|',因为这也能解决我认为的问题。 (是的,工程,derp) – user1189336 2012-02-07 14:04:37