我需要一个小脚本来过滤给定文本中的文献参考。引用可以采用两种格式:
bla bla bla(Snowden,2014a)bla bla bla(Bush and Blair,2005)bla bla bla。通过两次搜索找到这些参考资料:
matches1 = re.findall('\([A-Z]\w*,\s?\d\d\d\d[a-z]?\)', line)
matches2 = re.findall('\([A-Z]\w* and [A-Z]\w*,\s?\d\d\d\d[a-z]?\)', line)
这些搜索正确地找到(Snowden,2014a)。 (布什和布莱尔,2005年)。但现在我想在一次搜索中找到这两种引用,但它失败了:
matches1 = re.findall('\([A-Z]\w*( and [A-Z]\w*)?,\s?\d\d\d\d[a-z]?\)', line)
此搜索返回''而不是(斯诺登,2014a)和'和布莱尔'而不是(Bush和Blair,2005)。我不清楚为什么会发生这种情况或者我做错了什么,所以任何帮助都值得赞赏:)
谢谢!
答案 0 :(得分:2)
只需将捕获组转为非捕获组,然后将\d\d\d\d
缩减为\d{4}
。因为re.findall
给予群组首选。如果存在任何组,则它将仅打印组内存在的字符。它忘记了匹配的字符串。
\([A-Z]\w*(?: and [A-Z]\w*)?,\s?\d{4}[a-z]?\)
示例代码:
>>> import re
>>> s = """foo bar (Snowden, 2014a)
... (Bush and Blair, 2005) foo bar"""
>>> m = re.findall(r'\([A-Z]\w*(?: and [A-Z]\w*)?,\s?\d{4}[a-z]?\)', s, re.M)
>>> for i in m:
... print i
...
(Snowden, 2014a)
(Bush and Blair, 2005)
答案 1 :(得分:0)
通过添加?:
:
In [8]: re.findall('\([A-Z]\w*(?: and [A-Z]\w*)?,\s?\d\d\d\d[a-z]?\)', line)
Out[8]: ['(Snowden, 2014a)', '(Bush and Blair, 2005)']