You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python/正则表达式:LaTeX align*环境转自定义标签问题求助

问题描述

我有一个包含数千行内容的文件,示例内容如下:

\begin{align*}
  H_0 \amp : \mu_1 = \mu_2 = \mu_3 = \mu_4 = \mu_5 \\
  H_1 \amp : \text{Some text} \\
  H_2 \amp : \text{More text...} \\
\end{align*}

\begin{table}[htb]
  \centering
  \begin{tabular}{cc}
    Mean   \amp = \amp the mean value $\mu$       \\
    Median \amp = \amp the median value $\median$ \\
    Mode   \amp = \amp the mode value $\mode$     \\
  \end{tabular}
\end{table}

我的目标是将\begin{align*}...\end{align*}转换为:

<md>
  <mrow>H_0 \amp : \mu_1 = \mu_2 = \mu_3 = \mu_4 = \mu_5</mrow>
  <mrow>H_1 \amp : \text{Some text}</mrow>
  <mrow>H_2 \amp : \text{More text...}</mrow>
</md>

并将\begin{table}[htb]...\end{table}转换为:

<table>
  <tabular halign="center">
    <row header="yes" bottom="minor" >
      <cell>Mean</cell>
      <cell>=</cell>
      <cell>the mean value $\mu$</cell>
    </row>
    <row>
      <cell>Median</cell>
      <cell>=</cell>
      <cell>the mode value $\mode$</cell>
    </row>
    <row>
      <cell>Mode</cell>
      <cell>=</cell>
      <cell>the mode value $\mode$</cell>
    </row>
  </tabular>
</table>

目前我正在处理\begin{align*}部分,还没开始处理table环境。我写的脚本没达到预期效果,应该是用了re.escape(...)导致生成了过多不必要的\转义字符。我需要消除这些多余转义,同时移除\begin{align*}和\end{align*},求帮忙!

我的脚本及当前错误输出如下:

错误输出:

<md><mrow>\begin\{align\*\}\n\ \ H_0\ \amp\ :\ \mu_1\ =\ \mu_2\ =\ \mu_3\ =\ \mu_4\ =\ \mu_5\ </mrow><mrow>\n\ \ H_1\ \amp\ :\ \text\{Some\ text\}\ </mrow><mrow>\ \n\ \ H_2\ \amp\ :\ \text\{More\ text\.\.\.\}\ </mrow>\ \n\end\{align\*\}</md>

\begin{table}[htb]
  \centering
  \begin{tabular}{cc}
    Mean   \amp = \amp the mean value $\mu$       \\
    Median \amp = \amp the median value $\median$ \\
    Mode   \amp = \amp the mode value $\mode$     \\
  \end{tabular}
\end{table}

原脚本:

import re

my_file = open("sample.txt", "r")
data: str = my_file.read()
result: str = data

original = re.findall(r'\\begin{align\*}[\s\S]*\\end{align\*}', data,)
modified = re.findall(r'\\begin{align\*}[\s\S]*\\end{align\*}', data,)

for i in range(len(modified)):
  # append the first mrow of the <md> tag
  modified[i] = r'<mrow>' + modified[i] 
  # replace \\ with a closing and opening of </mrow> and <mrow>.
  modified[i] = str(modified[i]).replace(r'\\', r'</mrow><mrow>')
  #wrap everything with the math display environment
  modified[i] = '<md>' + modified[i]+r'</md>'
  # Remove the last <mrow> as it is an extra
  modified[i] =(modified[i][::-1].replace(r'<mrow>'[::-1], ''[::-1], 1))[::-1]
  
  
  result = re.sub(re.escape(original[i]), re.escape(modified[i]), result)
  # print(modified[i])
  # print(original[i])
  print(result)
解决方案

你的核心问题在于使用了re.escape(),它会把所有特殊字符都转义,导致输出里出现大量不必要的\。另外原脚本没有先剥离\begin{align*}和\end{align*}标签,直接处理整个匹配内容会把标签也包含进去。

修正后的脚本可以用正则的回调函数来处理每个匹配到的align块,步骤如下:

  1. 匹配\begin{align*}到\end{align*}的内容,捕获中间的行
  2. 剥离首尾的环境标签,拆分每行,过滤空行
  3. 对每行做处理:去除首尾空白,包裹<mrow>
  4. 把所有行用换行和缩进整理,包裹到<md>标签里

修正代码:

import re

def process_align_block(match):
    # 获取匹配到的align块内容,包含首尾标签
    block = match.group(0)
    # 剥离首尾的\begin{align*}和\end{align*}及周围空白
    content = re.sub(r'^\\begin{align\*}\s*|\s*\\end{align\*}$', '', block)
    # 按\\拆分每行,过滤掉空行并去除每行首尾空白
    lines = [line.strip() for line in content.split(r'\\') if line.strip()]
    # 给每行包裹<mrow>,并添加缩进
    mrows = ['  <mrow>' + line + '</mrow>' for line in lines]
    # 组合成最终的<md>结构
    return '<md>\n' + '\n'.join(mrows) + '\n</md>'

# 读取文件(用with语句自动关闭文件)
with open("sample.txt", "r") as my_file:
    data = my_file.read()

# 处理所有align*块
result = re.sub(r'\\begin{align\*}[\s\S]*?\\end{align\*}', process_align_block, data)

# 输出结果(也可以写入文件)
print(result)

代码解释

  • 使用re.sub的回调函数process_align_block,每个匹配到的align块都会被这个函数处理
  • 用正则^\\begin{align\*}\s*|\s*\\end{align\*}$去掉首尾的环境标签和周围空白
  • 按\\拆分每行,过滤空行后处理每行的首尾空白,避免生成多余空格
  • 最后整理成带缩进的格式,和你期望的输出完全一致

运行这个脚本后,align*部分会被正确转换,不会有多余的转义字符。后续处理table环境可以用类似的思路,匹配table块后再拆分tabular内容进行转换。

内容的提问来源于stack exchange,提问作者M. Al Jumaily

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 23:35:57