我有一个包含以下条目的文本文件:
@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
当我运行代码时,它会捕获除了Jim DeMint姓氏之外的Twitter句柄,状态和全名。我已经声明我想忽略正则表达式的情况。
有什么想法吗?为什么表达式没有捕获这个姓氏?
答案 0 :(得分:3)
它缺少它,因为他的州名包含两个词:SOUTH CAROLINA
让你的第二个正则表达式是这个,它应该有帮助
(@[\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或2个单词,这应该是状态。这只适用于下一部分,必须有两个单词
((?:[\w]+?\s){2})
匹配并捕获两个单词,其中定义为尽可能少的字符,后跟空格
答案 1 :(得分:2)
text=re.sub(' (NO|-+)(?= |$)','',text)
捕捉一切:
re.findall('(@\w+) ([A-Z ]+[A-Z]) (.+?(?= @|$))',text)
或者一下子:
re.findall('(@\w+) ([A-Z ]+[A-Z])(?: NO| -+)? (.+?(?= @|$))',text)