【问题标题】:Python regex to get citations in a paperPython 正则表达式在论文中获得引用
【发布时间】:2020-08-28 11:24:54
【问题描述】:

我正在使用 this code 从文本中提取引文:

#!/usr/bin/env python3
# https://stackoverflow.com/a/16826935

import re
from sys import stdin

text = stdin.read()

author = "(?:[A-Z][A-Za-z'`-]+)"
etal = "(?:et al.?)"
additional = "(?:,? (?:(?:and |& )?" + author + "|" + etal + "))"
year_num = "(?:19|20)[0-9][0-9]"
page_num = "(?:, p.? [0-9]+)?"  # Always optional
year = "(?:, *"+year_num+page_num+"| *\("+year_num+page_num+"\))"
regex = "(" + author + additional+"*" + year + ")"

matches = re.findall(regex, text)
matches = list( dict.fromkeys(matches) )
matches.sort()

#print(matches)
print ("\n".join(matches))

但是,它会将一些大写单词识别为作者姓名。比如在文中:

Although James (2020) recognized blablabla, Smith et al. (2020) found mimimi. 
Those inconsistent results are a sign of lalala (Green, 2010; Grimm, 1990). 
Also James (2020) ...

输出将是

Also James (2020)
Although James (2020)
Green, 2010
Grimm, 1990
Smith et al. (2020)

有没有办法在不删除整个匹配项的情况下将上述代码中的某些单词“列入黑名单”?我希望它能够识别 James 的工作,但从引文中删除了“Also”和“Although”。

提前致谢。

【问题讨论】:

    标签: python regex text citations


    【解决方案1】:

    你可以使用

    author = r"(?:[A-Z][A-Za-z'`-]+)"
    etal = r"(?:et al\.?)"
    additional = f"(?:,? (?:(?:and |& )?{author}|{etal}))"
    year_num = "(?:19|20)[0-9][0-9]"
    page_num = "(?:, p\.? [0-9]+)?"  # Always optional
    year = fr"(?:, *{year_num}{page_num}| *\({year_num}{page_num}\))"
    regex = fr'\b(?!(?:Although|Also)\b){author}{additional}*{year}'
    matches = re.findall(regex, text)
    

    请参阅Python demoresulting regex demo

    主要区别在于regex = fr'\b(?!(?:Although|Also)\b){author}{additional}*{year}',如果紧靠右边的单词是AlthoughAlso\b(?!(?:Although|Also)\b)部分将失败。

    另外,请注意我转义了应该与文字点匹配的点,并使用 f 字符串使代码看起来更紧凑。

    【讨论】:

    • 谢谢!最后是否有可能也删除页码?实际上他们都引用了同一个文件,但他们计算了两次。
    • @IuriGavronski 我不知道你想得到什么确切的输出。试试regex101.com/r/xssPEs/2
    • 我发现您指向的两个网站(regex101 和 ideone)很棒。谢谢!我相信你搞定了。事实上,我最好的情况是以标准格式输出所有引用,例如 James (2020),因此 list(dict()) 会删除重复条目。我的最终游戏是将学术论文末尾的参考文献列表与文本中的引文进行比较。这是一个非常耗时的过程,而这个脚本在缩短这个过程中还有很长的路要走。
    【解决方案2】:

    这是我的答案,之前的答案不适用于某些引用。

    regexr.com/6er6n
    

    我从其他来源获得的这个答案,但它不适用于另一种类型的引文文本。我的版本修复了这个问题:

    citationsRegex = r"\b(?!(?:Although|Also)\b)(?:[A-Z][A-Za-z'`-]+)(?:,? (?:(?:and |& )?(?:[A-Z][A-Za-z'`-]+)|(?:et al.?)))*(?:,? *(?:19|20)[0-9][0-9](?:, p\.? [0-9]+)?| *\((?:19|20)[0-9][0-9](?:, p\.? [0-9]+)?\))"
    

    【讨论】:

    • 您能解释一下为什么您的正则表达式模式不能正确提取一些引用吗?
    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
    • 与我的解决方案的唯一区别是一个,?(在(?:et al.?)))*(?:,?)被替换为,,所以你建议的只是强制使用逗号。
    • 我们可以写成,+,而不是一个逗号。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-27
    • 1970-01-01
    相关资源
    最近更新 更多