【问题标题】:Regex and python: substituting $$ with \[ and \] in a TeX document正则表达式和 python:在 TeX 文档中用 \[ 和 \] 替换 $$
【发布时间】:2015-05-17 13:12:38
【问题描述】:

编辑: 带有测试、示例和解决方案的正则表达式:https://www.regex101.com/r/rY7uI4/2

我正在尝试转换 TeX 内容(我们将假定它包含在变量 foo 中),以便将分隔符 $$ 转换为标准 TeX \[\]。我一直在玩 regex101,但直到现在还没有运气。

理想情况下,预期结果是给定以下输入:

text
$$ math $$

$$
math
$$

text $$math$$ text

输出如下

text
\[ math \]

\[
math
\]

text \[math\] text

也许正则表达式不是最好的工具,但我没有找到其他工具来完成这项任务。感谢您的帮助!

编辑: 添加一个更复杂(和现实)的测试用例:

$$\alpha \quad \beta \quad \varepsilon \quad \varphi \quad \mathbb{R} \quad \mathcal{C}([0,1]) \quad \mathfrak{R}([0,2\pi]) \quad \mathscr{C}(\mathbb{R})$$
$$\vec{x} \in \mathbb{R}^n, \quad \underline{x}\in \mathbb{R}^m, \quad \mathbf{x}\in \mathbb{R}^m \$$$string

应该导致:

\[\alpha \quad \beta \quad \varepsilon \quad \varphi \quad \mathbb{R} \quad \mathcal{C}([0,1]) \quad \mathfrak{R}([0,2\pi]) \quad \mathscr{C}(\mathbb{R})\]
\[\vec{x} \in \mathbb{R}^n, \quad \underline{x}\in \mathbb{R}^m, \quad \mathbf{x}\in \mathbb{R}^m \$\]string

注意第二个字符串末尾的转义 $。

【问题讨论】:

  • 你不能用简单的str.replace吗?
  • 如果你想用其他固定字符串替换固定字符串(不是patterns),标准问题字符串替换功能就是你想要的。不要把事情复杂化。
  • 不幸的是 str.replace 将替换它找到的所有出现,而我只希望,对于每对 $$,第一个 $$ 替换为 \[,第二个替换为\]

标签: python regex replace tex file-conversion


【解决方案1】:

您可以使用re.subcapturing groups,如下所示:

>>> import re
>>> s="""text
... $$ math $$
... 
... $$
... math
... $$
... 
... text $$math$$ text"""
>>> print re.sub(r'\$\$\s?(\w+)\s?\$\$',r'\[\1\]',s)
text
\[math\]

\[math\]

text \[math\] text

\1 是在这种情况下 (\w+) 的正则表达式模式中匹配的第一组

编辑:如果您在编辑中添加时$$ 之间可能有更多文本,您只需更改与.+ 匹配单词字符的\w 以匹配长度超过1 的任何字符。

>>>re.sub(r'\${2,}\s?(.+?)\s?\${2,}',r'[\1]',s)

【讨论】:

  • 嗨!谢谢,第一个版本确实是正确的(我需要\[,而不是[),我确认它有效!!!
  • 对不起,我说得太早了:像$$\alpha \quad \beta \quad \varepsilon \quad \varphi \quad \mathbb{R} \quad \mathcal{C}([0,1]) \quad \mathfrak{R}([0,2\pi]) \quad \$ \mathscr{C}(\mathbb{R})$$ 这样的字符串(在TeX 文档中非常典型)无法被该正则表达式识别。
  • @Roophie 那么你的预期输出是什么?你能把它加到你的问题上吗?
  • @Roophie >>> print re.sub(r'\${2,}\s?(.+?)\s?\${2,}',r'[\1]',s)
【解决方案2】:

使用非贪婪的正则表达式。

print re.sub(r'\$\$(.*?)\$\$',r'\[\1\]',s)

如果您不想考虑转义的美元符号,请使用否定的lookbehind 来检查最后一个$$ 前面是否没有反斜杠字符。

print re.sub(r'(?s)(?<!\\)\$\$(.*?)(?<!\\)\$\$',r'\[\1\]',s)

在开头添加 DOTALL 修饰符 (?s) 以在正则表达式中添加点以匹配换行符(换行符)。

【讨论】:

  • 几乎完美,即使它会失败:$$test\$$$ string
  • 所以你不想考虑转义 $ ?试试\$\$(.*?)(?&lt;!\\)\$\$(?&lt;!\\)\$\$(.*?)(?&lt;!\\)\$\$
  • 是的,完全正确。它几乎就在那里,但是,如果输入包含换行符(也经常出现),则会中断。
  • 然后在开头添加一个 DOTALL 修饰符,例如 print re.sub(r'(?s)(?&lt;!\\)\$\$(.*?)(?&lt;!\\)\$\$',r'\[\1\]',s)
猜你喜欢
  • 1970-01-01
  • 2010-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-13
  • 1970-01-01
相关资源
最近更新 更多