特定术语前的负面正则表达式

Gio*_*gio 6 python regex latex

我想解析一个LaTeX文档,并用一个特殊的命令标记它的一些术语.具体来说,我有一个术语列表,比如说:

Astah
UML
use case
...
Run Code Online (Sandbox Code Playgroud)

我想用这个自定义命令标记文本中第一次出现的Astah : \gloss{Astah}. 到目前为止,这是有效的(使用Python):

for g in glossary:
    pattern = re.compile(r'(\b' + g + r'\b)', re.I | re.M)
    text = pattern.sub(start + r'\1' + end, text, 1)
Run Code Online (Sandbox Code Playgroud)

它工作正常.

但后来我发现:

  • 不想匹配LaTeX内联注释后的术语(所以术语前面有一个或多个%)
  • 而且我不想匹配部分标题内的术语(即\section{term}\paragraph{term})

所以我尝试了这个:

for g in glossary:
    pattern = re.compile(r'(^[^%]*(?!section{))(\b' + g + r'\b)', re.I | re.M)
    text = pattern.sub(r'\1' + start + r'\2' + end, text, 1)
Run Code Online (Sandbox Code Playgroud)

但它匹配注释中的术语,前面是其他字符,它也匹配标题内的术语.

关于正则表达式的"贪婪",我不明白吗?或者问题可能在别的地方?

举个例子,如果我有这个文字:

\section{Astah}
Astah is a UML diagramming tool... bla bla...
% use case:
A use case is a...
Run Code Online (Sandbox Code Playgroud)

我想将其转换为:

\section{Astah}
\gloss{Astah} is a \gloss{UML} diagramming tool... bla bla...
% use case:
A \gloss{use case} is a...
Run Code Online (Sandbox Code Playgroud)

Ara*_*Fey 1

这里的技巧是使用从行首开始匹配的正则表达式,因为这允许我们检查我们尝试匹配的单词前面是否有注释:

^([^%\n]*?)(?<!\\section{)(?<!\\paragraph{)\b(Astah)\b
Run Code Online (Sandbox Code Playgroud)

需要多行标志m。此正则表达式的出现将替换为\1\\gloss{\2}.