2012-02-04 145 views
3

我正在做一個Python項目,需要用戶輸入文本。如果文本與程序支持的格式匹配,它將輸出一個包含用戶關鍵字(它是一個簡單的聊天機器人)的響應。該格式作爲用戶輸入格式和答案格式存儲在文本文件中。如何在佔位符文本中使用Python中的正則表達式?

例如,文本文件看起來像這樣,用戶輸入在左,輸出在右:

my name is <-name> | Hi there, <-name> 

所以,如果用戶寫my name is johnny,我想程序知道johnny<-name>變量,然後打印響應Hi there, johnny

有些刺激我的方向是正確的!我之前從未使用正則表達式,並且閱讀了一篇關於如何使用它們的文章,但不幸的是,它並沒有真正幫助我,因爲它主要涉及如何匹配特定單詞。

+0

不完全確定,你在這裏問。 REGEXP是關於加工特定的字符串結構(即單詞),還有什麼?任何類型的語義分析都是完全不同的東西。 – hasienda 2012-02-04 13:22:24

回答

7

下面是一個例子:

import re 

io = [ 
    ('my name is (?P<name>\w+)', 'Hi there, {name}'), 
] 

string = input('> ') 
for regex, output in io: 
    match = re.match(regex, string) 
    if match: 
     print(output.format(**match.groupdict())) 
     break 

我帶你去通過它:


'my name is (?P<name>\w+)' 

(?P<name>...)存儲以下部分(\w+)這個名字name下的比賽對象,我們將在稍後使用。


match = re.match(regex, string) 

這會在給定的輸入regex。請注意,re.match只匹配開頭的輸入,如果您不想在此處使用此限制,請使用re.search


如果匹配:

output.format(**match.groupdict()) 

match.groupdict返回由(?P<name>...)及其相關聯的匹配的值定義鍵的字典。 **將這些鍵/值傳遞給.format,在這種情況下,Python會將其轉換爲output.format(name='matchedname')


構建從文件中io字典做這樣的事情:

io = [] 
with open('input.txt') as file_: 
    for line in file: 
     key, value = line.rsplit(' | ', 1) 
     io.append(tuple(key, value)) 
+0

+1,我喜歡這個。它乾淨而優雅。雖然它並沒有真正解決文件輸入的問題。 – 2012-02-04 13:24:35

+0

我相信我的re.sub版本,和這個(因爲我沒有解決多個潛艇的問題)可以合併來簡化它。字符串格式和匹配組可能會成爲一個子 - 雖然我也看到,re.sub版本不會表明一個子實際上已經被創建。 – 2012-02-04 13:29:16

+0

@NiklasBaumstark,真的。沒有認爲這是問題的相關部分。儘管這很簡單,但爲了完整起見,我會將其添加到我的答案中。 – 2012-02-04 13:30:17

0

看看re模塊並注意捕捉組。

例如,你可以假設名稱將是一個字,所以它匹配\w+。然後,你必須構建與\w+捕獲組,其中名稱應爲(捕獲組用括號分隔)正則表達式:

r'my name is (\w+)' 

,然後匹配它的輸入(提示:re模塊中尋找match文檔)。

一旦你的比賽,你必須得到捕獲組的內容(在索引1,索引0在這種情況下,是保留給整場比賽),並用它來構建你的迴應。

4

你要想做一個小組賽,然後拔出搜索組。

首先你想要import re - re是python正則表達式模塊。 可以說,user_input是持有輸入字符串的var。 然後,您想使用re.sub方法來匹配您的字符串,並返回替代它的東西。

output = re.sub(input_regex, output_regex, user_input)

所以正則表達式,首先你可以把你想要絕對的東西:

input_regex = 'my name is '

如果你想讓它從該行的開始明確地匹配,你應該繼續它與插入符號:

input_regex = '^my name is '

然後你想要一組匹配任何字符串。+(。是什麼,+是前面的項目的1或更多)直到行'$'結束。

input_regex = '^my name is .+$'

現在,你想把他們到一個組。命名組的形式爲「(?Pregex)」 - 請注意,這些尖括號是文字。

input_regex = '^my name is (?P<name>.+)$'

您現在有一個正則表達式將匹配並給予命名爲「名」與它的用戶名匹配的組。輸出字符串需要用「\ G」

output_regex = 'Hi there, \g<name>'

引用匹配組全部放在一起,你能做到這一點的一個襯墊(和進口):

import re 
output = re.sub('^my name is (?P<name>.+)$', 'Hi there, \g<name>', user_input) 
1

問對於REGEXP來說,不可避免地會導致類似於你現在正在獲得的答案:REGEXP基本操作的演示:如何分割句子,搜索某些術語組合,例如「我的」+「名稱」+「是」等。

事實上,你可以學習所有t他從閱讀現有的文檔和開源程序。 REGEXP並不簡單。如果你想改變和擴展你的程序,你仍然需要自己理解一點才能真正知道發生了什麼。不要僅僅從收據中複製。

但你甚至可能想要更全面的東西。因爲您提到了構建「聊天機器人」,您可能希望看到,超越REGEXP的方式。請參閱:

所以,如果用戶寫「我的名字是約翰尼」,我想程序知道,「約翰尼」是「< -name>」變量,...

從你的問題還不清楚,這個程序應該變得多複雜。什麼,如果他類型

'Johnny is my name.' 

'Hey, my name is John X., but call me johnny.' 

相關問題