1

次のようなエントリを含むテキストファイルがあります。

@markwarner VIRGINIA - Mark Warner 
@senatorleahy VERMONT - Patrick Leahy NO 
@senatorsanders VERMONT - Bernie Sanders 
@orrinhatch UTAH - Orrin Hatch NO 
@jimdemint SOUTH CAROLINA - Jim DeMint NO 
@senmikelee UTAH -- Mike Lee 
@kaybaileyhutch TEXAS - Kay Hutchison 
@johncornyn TEXAS - John Cornyn 
@senalexander TENNESSEE - Lamar Alexander

正規表現を使用して「NO」とダッシュを削除するために、次のように記述しました。

import re

politicians = open('testfile.txt')
text = politicians.read()

# Grab the 'no' votes
# Should be 11 entries
regex = re.compile(r'(no\s@[\w+\d+\.]*\s\w+\s?\w+?\s?\W+\s\w+\s?\w+)', re.I)
no = regex.findall(text)

## Make the list a string
newlist = ' '.join(no)

## Replace the dashes in the string with a space
deldash = re.compile('\s-*\s')
a = deldash.sub(' ', newlist)

# Delete 'NO' in the string
delno = re.compile('NO\s')
b = delno.sub('', a)

# make the string into a list
# problem with @jimdemint SOUTH CAROLINA Jim DeMint
regex2 = re.compile(r'(@[\w\d\.]*\s[\w\d\.]*\s?[\w\d\.]\s?[\w\d\.]*?\s+?\w+)', re.I)
lst1 = regex2.findall(b)

for i in lst1:
    print i

コードを実行すると、Twitterのハンドル、状態、およびJimDeMintの名前以外のフルネームがキャプチャされます。正規表現の場合は無視したいと述べました。

何か案は?式がこの名前をキャプチャしないのはなぜですか?

4

2 に答える 2

3

彼の州名には2つの単語が含まれているため、欠落しています:SOUTH CAROLINA

2番目の正規表現をこれにします。役立つはずです

 (@[\w\d\.]*\s[\w\d\.]*\s?[\w\d\.]\s?[\w\d\.]*?\s+?\w+(?:\s\w+)?)

追加した

(?:\s\w+)?

これは、スペースとそれに続く1つ以上の英数字の下線文字に一致するオプションの非キャプチャグループです。

http://regexr.com?31fv5は、入力がNOとダッシュが削除された状態で適切に一致することを示しています。

編集: 1つのマスター正規表現ですべてを適切にキャプチャして分割する場合は、番号とダッシュを削除した後、次を使用します

((@[\w]+?\s)((?:(?:[\w]+?)\s){1,2})((?:[\w]+?\s){2}))

ここで遊ぶことができるもの:http://regexr.com?31fvk

完全一致は$1で、Twitterハンドルは$ 2で、州は$ 3で、名前は$4で入手できます。

各キャプチャグループは次のように機能します。

(@[\w]+?\s)

これは、@記号の後に、スペースが入るまで少なくとも1文字、ただしできるだけ少ない文字が続くものと一致します。

((?:(?:[\w]+?)\s){1,2})

これは、状態であるはずの1つまたは2つの単語に一致してキャプチャします。これは次のピースのためにのみ機能します。次のピースには2つの単語が必要です。

((?:[\w]+?\s){2})

正確に2つの単語に一致してキャプチャします。これは、可能な限り少ない文字とそれに続くスペースで定義されます。

于 2012-07-09T20:44:22.127 に答える
2
text=re.sub(' (NO|-+)(?= |$)','',text)

そして、すべてをキャプチャするには:

re.findall('(@\w+) ([A-Z ]+[A-Z]) (.+?(?= @|$))',text)

または一度に:

re.findall('(@\w+) ([A-Z ]+[A-Z])(?: NO| -+)? (.+?(?= @|$))',text)
于 2012-07-09T20:39:14.683 に答える