在 python 中使用正则表达式从 tex 文件中提取引用的 bibtex 键

Extract cited bibtex keys from tex file using regex in python

我正在尝试使用 python 中的正则表达式从 LaTeX 文档中提取引用的 BibTeX 键。

如果引文被注释掉(前面有 %),我想将其排除,但如果前面有百分号 (\%),我仍将其包括在内。

这是我到目前为止的想法:

\(?:no|)cite\w*\{(.*?)\}

试用示例:

blablabla
Author et. al \cite{author92} bla bla. % should match
\citep{author93} % should match
\nocite{author94} % should match
100\%\nocite{author95} % should match
100\% \nocite{author95} % should match
%\nocite{author96} % should not match
\cite{author97, author98, author99} % should match
\nocite{*} % should not match

Regex101 测试:https://regex101.com/r/ZaI8kG/2/

感谢任何帮助。

使用较新的 regex 模块 (pip install regex),表达式如下:

(?<!\)%.+(*SKIP)(*FAIL)|\(?:no)?citep?\{(?P<author>(?!\*)[^{}]+)\}

参见a demo on regex101.com


更详细:

(?<!\)%.+(*SKIP)(*FAIL)     # % (not preceded by \) 
                             # and the whole line shall fail
|                            # or
\(?:no)?citep?              # \nocite, \cite or \citep
\{                           # { literally
    (?P<author>(?!\*)[^{}]+) # must not start with a star
\}                           # } literally


如果安装另一个库不是一个选项,则需要将表达式更改为

(?<!\)%.+
|
(\(?:no)?citep?
\{
    ((?!\*)[^{}]+)
\})

并且需要以编程方式检查第二个捕获组是否已设置(即不为空)。
后者可能在 Python:

import re

latex = r"""
blablabla
Author et. al \cite{author92} bla bla. % should match
\citep{author93} % should match
\nocite{author94} % should match
100\%\nocite{author95} % should match
100\% \nocite{author95} % should match
%\nocite{author96} % should not match
\cite{author97, author98, author99} % should match
\nocite{*} % should not match
"""

rx = re.compile(r'''(?<!\)%.+|(\(?:no)?citep?\{((?!\*)[^{}]+)\})''')

authors = [m.group(2) for m in rx.finditer(latex) if m.group(2)]
print(authors)

产生

['author92', 'author93', 'author94', 'author95', 'author95', 'author97, author98, author99']

我没有遵循最后一个逻辑,在我看来 *{} 中可能不需要,在那种情况下,也许您想设计一个表达式类似于:

^(?!(%\(?:no)?cite\w*\{([^}]*?)\}))[^*\n]*$

虽然不确定。

DEMO