2012-02-04 38 views
3

私はユーザーがテキストを入力する必要があるプロジェクトをPythonでやっています。テキストがプログラムでサポートされている形式と一致する場合、ユーザーのキーワード(単純なチャットボット)を含むレスポンスが出力されます。形式は、ユーザー入力形式と応答形式としてテキストファイルに格納されます。たとえば、テキストファイルが右に左と出力のユーザー入力で、次のようになりますプレースホルダテキストでPythonで正規表現を使用するにはどうすればよいですか?

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

したがって、ユーザーは、私はプログラムがjohnnyであることを知ってほしい、my name is johnnyを書き込んだ場合<-name>変数を入力し、応答Hi there, johnnyを印刷します。

正しい方向に私を驚かせるものもあります。以前は正規表現を使ったことが一度もありませんでしたが、使用方法に関する記事を読んでいましたが、残念ながら特定の単語のマッチング方法を主に巡って以来、本当に助けにはなりませんでした。

+0

完全にはわかりませんが、ここで何を求めているのですか? REGEXPは、特定の文字列構造(言い方を言えば)を加工することに関するものです。あらゆる意味論的分析はまったく別のものです。 – hasienda

答えて

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 

私はそれを通してあなたを取るよ:どのマッチオブジェクト内の名前name


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

(?P<name>...)店舗以下の部分(\w+を)私たちは後で使うつもりです。


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、私はこれが好きです。清潔でエレガントです。それは実際にファイルの入力事項に対処するものではありません。 –

+0

私は私のre.subバージョンとこれは(私は複数のサブものに対処しなかったので)それを単純化するために組み合わせることができると確信しています。文字列フォーマットとマッチグループはサブ - となるかもしれませんが、私はre-versionもサブが実際に作られたことを示していないことがわかります。 @ NiklasBaumstark、true。 –

+0

その質問の関連部分としては考慮しなかった。しかし、それはかなり簡単ですので、私は完全にするために私の答えに追加します。 –

0

reモジュールを見て、グループのキャプチャに注意してください。

たとえば、名前が単語であると仮定すると、\w+に一致します。そして、あなたは名前が(キャプチャグループは、括弧で区切られている)である必要があり\w+キャプチャグループで正規表現を構築する必要があります。

r'my name is (\w+)' 

し、入力に対してそれを一致させる(ヒント:reモジュールにmatchを探しますdocs)。

マッチを取得したら、キャプチャグループの内容を取得する必要があります(この場合はインデックス1、インデックス0はマッチ全体に予約されています)。ここで

4

あなたはグループのマッチを行うと、検索グループを引き出したいしようとしています。

最初にimport reにしたいと思う - reはpython regexモジュールです。 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>.+)$'

あなたは今のユーザー名を指定して、「名前」という名前の一致グループと一致して与える正規表現を持っています。出力文字列を使用すると、1つのライナー(およびインポート)でそれを行うことができます

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

はすべて一緒にそれを置く「\ gを」との一致グループを参照する必要があります。

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

尋ねます基本的なREGEXP操作のデモンストレーション:REGEXPは、必然的にあなたが今取得しているもののような答えにつながるため、文章を分割する方法を「私の」+「名前」+のようないくつかの用語を組み合わせて検索することなど、内

「です」

実際、あなたはすべてのt彼は既存のドキュメンテーションとオープンソースプログラムを読んでいません。 REGEXPは簡単ではありません。プログラムを変更して拡張したい場合、実際に何が起こっているのかを実際に知るためには、ちょっと理解する必要があります。領収書からコピーするだけではありません。

しかし、あなたはもっと総合的な何かを持っている場合があります。あなたが "チャットボット"を構築することに言及したので、あなたはhow others are approaching that task - REGEXPを超えて見ることができます。参照:

だから、ユーザーが「私の名前はジョニー」で書けば、私は、プログラムは「ジョニーは」「< -name>」変数であることを知ってほしいです...

質問から、このプログラムがどのくらい複雑になるかは不明です。何、もし彼のタイプ

'Johnny is my name.' 

または

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

関連する問題