我想解析一个LaTeX文档并用一个特殊的命令标记它的一些术语。具体来说,我有一个术语列表,比如:
Astah
UML
use case
...
我想用这个自定义命令来标记文本中第一个出现的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)
而且效果很好。你知道吗
但后来我发现:
%
)\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)
但它匹配注释中前面有其他字符的术语,也匹配标题中的术语。你知道吗
是不是关于正则表达式的“贪婪”我不明白?或者问题出在别的地方?你知道吗
举个例子,如果我有这段文字:
\section{Astah}
Astah is a UML diagramming tool... bla bla...
% use case:
A use case is a...
我想把它变成:
\section{Astah}
\gloss{Astah} is a \gloss{UML} diagramming tool... bla bla...
% use case:
A \gloss{use case} is a...
这里的诀窍是使用一个regex,从行首开始匹配,因为这允许我们检查要匹配的单词前面是否有注释:
需要多行标志
m
。此正则表达式的出现将替换为\1\\gloss{\2}
。你知道吗这是我的两分钱:
首先,我们需要使用regex module by Matthew Barnett。它带来了许多有趣的特性。在这种情况下,它的一个特性可能很有用,即添加的
(*SKIP)
和(*FAIL)
。你知道吗从documentation:
因此,让我们构建模式并使用regex模块进行测试:
输出:
模式:
这句话很好地说明了这一点:
在左边,我们将写下我们不想要的上下文。在右边(最后一部分),我们捕捉到我们真正想要的东西。所以所有的上下文都被一个交替符号
|
分开,最后一个(我们想要的)被捕获。你知道吗因为在这种情况下,我们将进行更换,所以我们需要(*跳过)(*失败)以保持我们不想更换的匹配零件完好无损。你知道吗
模式的含义:
这个简单的技巧在RexEgg上更为详细。你知道吗
希望有帮助。你知道吗
相关问题 更多 >
编程相关推荐