【问题标题】:Extracting all Latex commands from a Latex code File从 Latex 代码文件中提取所有 Latex 命令
【发布时间】:2015-03-23 18:22:32
【问题描述】:

我正在尝试从 tex 文件中提取所有 Latex 命令。我必须为此使用 Python。我尝试使用 Re 模块提取列表中的乳胶命令。

问题在于该列表不包含名称中包含特殊字符(如\alpha*、\a'、\#、\$、+、:、\;等)的latex 命令。它只包含由字母组成的乳胶命令。

我目前正在使用 re.match python 命令:

    "I already know the starting index of '\' which is at self.i.
     The example Latex code string could be:
     \documentclass[envcountsame,envcountchap]{svmono}"

     match_text = re.match("[\w]+", search_string[self.i + 1:])

我能够提取“文档类”。但是假设有另一个命令,例如:

     "\abstract*[alpha]{beta}"
     "\${This is a latex document}"
     "\:" 

如何从这些字符串中仅提取 'abstract*'、'$'、':'?

我是 Python 新手,尝试了各种方法,但无法提取所有这些命令名称。如果有一个通用的 python 正则表达式可以处理所有这些情况,那将会很有用。

注意:一本名为“The Not So Short Introduction to LaTeX”的书定义了 LaTeX 命令的格式可以分为三种类型 -

格式:

  • 它们以反斜杠 \ 开头,然后具有由以下组成的名称 仅限字母。命令名称以空格、数字或 任何其他“非字母”。

  • 它们由一个反斜杠和一个非字母组成。

  • 许多命令存在于“星号变体”中,其中一个星号附加到命令名称中。

【问题讨论】:

  • 似乎r'\\([a-zA-Z]+)(\*)?'re.findall 一起使用时差不多...
  • 对于包命令,@ 是一个字母,但如果没有更大的文件上下文,您就无法捕捉到这种情况,即不能合理地使用正则表达式。
  • \abstract*[alpha]{beta} 实际上是命令\abstract 带有三个参数,星号本身,可选的第二个参数和用大括号括起来的普通参数,那么为什么要使用第一个参数,如果它是星号而不是其他地方?

标签: python regex latex


【解决方案1】:

这是您的格式规范的准确翻译:

\\(?:[^a-zA-Z]|[a-zA-Z]+)\*?

Demo

  • 非信:[^a-zA-Z]
  • 或信件:[a-zA-Z]+
  • 已加星标的变体:\*?

如果您的格式描述准确,应该这样做。不幸的是,我不知道 LaTeX,所以我不确定它是否 100% OK。


从 cmets 中的反馈来看,星号仅适用于字母命令,还可以有其他一些终止字符。最终的正则表达式是:

\\(?:[^a-zA-Z]|[a-zA-Z]+[*=']?)

【讨论】:

  • +1 没有标准的单字符命令带有星号变体(据我所知),所以\\(?:[^a-zA-Z]|[a-zA-Z]+\*?)(未选中)也可以工作。还有各种其他情况(TeX 的标记器是……特殊的),但这应该会在“正常”文档中获得大多数命令,很少有误报。
  • 谢谢。对此表示赞同。这似乎在大多数情况下都有效,除了一种。只有一种特殊类型的案件没有被处理。我们有某些以字母开头并以不同于星号的非字母结尾的乳胶命令。例如,“\a=”、“\a'”等。如果你能想到稍微修改的正则表达式,那就太好了。
  • @shanu 当然,如果您有可能的字符列表,则很容易修改。 \\(?:[^a-zA-Z]|[a-zA-Z]+[*=']?) 将与您在评论中提到的人一起使用。
  • 太棒了。现在完美运行。谢谢。
  • The TeX book 开始,并且有人在此处包含,多字母命令后面的空格必须包含在命令名称中(用于分隔目的,而不是用于匹配命令名称) 因此,您的正则表达式会以\begin {} 之类的形式失败。更好的正则表达式是:\\([A-Za-z]+ *|.|\n)。但是要小心重音字符之类的命令,因为它们看起来有点像Espa\~nol,你会得到不希望的效果。带星号的命令在\LaTeX 中被视为第一个参数是星号。为什么实际上你想消除 \LaTeX 的东西?
【解决方案2】:

LaTeX 是一个 TeX 宏包,因此,适用于 TeX 的所有内容也适用于 LaTeX。

您提出的问题很困难,因为 TeX 不是常规语言。如果您只想处理命令,则必须检查 \\([A-Za-z]+ *|.|\n) 正则表达式(请参阅 demo),并注意在 TeX 中您有 活动字符,即只有在场就像一个命令。如果要处理命令参数,则必须检查各个命令定义,因为 TeX 是波兰表示法(运算符或命令是前缀,具有可变数量的位置参数)语言。对于参数提取,TeX 使用与上下文无关且不规则的大括号匹配,因此您需要一个完整的解析器。

TeX 允许您重新定义所有字符类,因此您可以重新定义数字以充当字母,并可用作命令名称(例如,\a23 是一个有效的命令名称)(这发生在包定义中,其中@ 用作字母,以便能够发出用户无法访问但在包内可用的命令)

由于这个原因,消除 LaTeX 标记是一件困难的事情,而且您只能获得部分结果。有许多不同的问题需要解决(如何处理\include 指令,如何处理\chapter 参数或\footnote 等参数中的有效文本,您希望包含索引等)

另外,你必须小心,如果你试图消除命令参数,你也会消除部分文本(例如\footnote\abstract\title、@987654331 中的文本@等)我不知道你真正想要得到的效果,所以我不能给你更多这方面的信息。

【讨论】:

    猜你喜欢
    • 2010-11-26
    • 1970-01-01
    • 2016-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-07
    • 2011-05-25
    相关资源
    最近更新 更多