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

我编写了以下内容以使用正则表达式删除“否”和破折号:

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

当我运行代码时,它会捕获除了 Jim DeMint 的姓氏之外的 twitter 句柄、状态和全名。我已经说过我想忽略正则表达式的大小写。

有任何想法吗?为什么表达式没有捕捉到这个姓氏?

4

2 回答 2

3

缺少它是因为他的州名包含两个词:南卡罗来纳州

让你的第二个正则表达式是这样的,它应该有帮助

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

我添加了

(?:\s\w+)?

这是一个可选的非捕获组,匹配一个空格后跟一个或多个字母数字下划线字符

http://regexr.com?31fv5显示它正确匹配输入与 NO 和破折号剥离

编辑: 如果您希望一个主正则表达式正确捕获和拆分所有内容,请在删除 Nos 和破折号后,使用

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

你可以在这里玩:http ://regexr.com?31fvk

完整匹配为 1 美元,Twitter 句柄为 2 美元,州为 3 美元,名称为 4 美元

每个捕获组的工作方式如下:

(@[\w]+?\s)

这匹配一个@符号,后跟至少一个但尽可能少的字符,直到一个空格。

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

这匹配并捕获了 1 个或两个单词,应该是状态。这只适用于下一段,它必须有两个词

((?:[\w]+?\s){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 回答