我需要设计一个复杂的 REGEX 模式,但在相当长的一段时间内我没有取得重大进展:
基本上我想从文本中提取作者年份的引用。我使用 REGEX 从括号中的文本中提取了引用
\(\K[^\)]+
有几种情况和变体可以找到作者:
Simple: Smith, 2000 or Smith 2000
Multiple authors: Smith/Miller 2001 or Smith & Miller, 2001
Authors with hyphens: Smith-Miller, 2001, Max-Planck-Society, 2001
Authors with accents: O'Neill 2001
Organizations with all caps: ACME Company
And permutations of the above cases
由于我只将文本保留在括号内,因此消除了大多数误报,但存在一些特殊情况:
- 等人/etal./u.a./u. A。需要保留
- 名称后应有年份 ([0=9]{4})
- 有时姓氏后面有逗号(Miller/Smith,2001)
- 需要支持国际字符
最简单的方法是:
\b[\p{Lu}\/].*?[0-9]{4}\b
但事实证明它过于贪婪,导致产生大量不需要的文本。
到目前为止,我最好的方法是:
(([\p{Lu}]+[\p{Lu}\p{Ll}\-\' ]*)+)([\/](?1))*([ ](et[ ]{0,1}al\.)|(u\.[ ]{0,1}a\.)){0,1}[,]*([ ][0-9]{4})
但它有一些问题:
- 仅当有逗号(,)时才识别多人
- 因此无法识别 Smith/Miller 2001,但 Smith/Miller, 2001 可以。
有一个简单的工作解决方案吗?喜欢:得到一切,那
- 不以小写字母开头
- 可以包含[\'/]
- 后跟 4 位数字:[0-9]{4}
- 可以包含“et. al.”数字之前
- 可以用/分隔
我尝试在这里测试正则表达式及其用例:https://regex101.com/r/HEA0rg/8
最佳答案
您可以使用重复模式(其中分隔符为空格或正斜杠)来匹配以大写字符开头的单词,并使 et al.
部分可选。
如果支持 \h
,您可以使用它来匹配 1 个以上水平空白字符而不是空格。
\p{Lu}[\p{Lu}\p{Ll}'-]*(?:[ \/]\p{Lu}[\p{Lu}\p{Ll}'-]*)*(?: et al\.)?,? [0-9]{4}
图案部分
\p{Lu}
匹配大写字符[\p{Lu}\p{Ll}'-]*
匹配字符类中重复 0 次以上的内容(?:
非捕获组[\/]\p{Lu}
匹配空格或/
,以大写字符 a 开始匹配[\p{Lu}\p{Ll}'-]*
匹配任意列出的 0 次以上
)*
关闭组并重复 0 次以上(?: et al\.)?
可选择匹配 et al.,? [0-9]{4}
匹配可选的逗号和空格,然后匹配 4 位数字
关于用于查找作者年份引用的正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57728538/