在python中使用regexp替换Latex命令

时间:2017-11-12 16:11:26

标签: python parsing latex

我编写了一个非常难看的脚本,以便在python中解析一些乳胶行并进行字符串替换。我在这里是因为我想写一些值得骄傲的东西,并且学习:P

更具体地说,我想改变:

  • \ket{(.*)}加入|(.*)\rangle
  • \bra{(.*)}加入\langle(*)|

为此,我写了一个非常丑陋的剧本。预期用途是做这样的事情:

cat file.tex | python script.py > new_file.tex

所以我做的是以下内容。它工作正常,但并不好看,我想知道你是否可以给我一个建议,即使是正确使用命令的链接也没关系。请注意我做递归,因为当我找到第一个“\ ket {”我知道我想要替换第一个出现的“}”(即我确定“\ ket {”)中没有其他子命令。但同样,这不是解析乳胶的正确方法。

def recursion_ket(string_input, string_output=""):
    match = re.search("\ket{", string_input)
    if not match:
        return string_input
    else:
        string_output = re.sub(r"\\ket{", '|', string_input, 1)
        string_output_second =re.sub(r"}", "\rangle", stringa_output.split('|', 1)[1],  1)
        string_output = string_output.split('|', 1)[0]+string_output_second
        string_output=recursion_ket(string_output, string_output)
    return string_output

if __name__ == '__main__':
    with open(sys.argv[1]) as f:
        content=f.readlines()
        new=[]
        for line in content:
            new.append(ricorsione_ket(line))
        z=open(sys.argv[2], 'w')
        for i in new:
            z.write(i.replace("\r", '\\r').replace("\b", '\\b'))
            z.write("")

我所知道的非常难看。这绝对不是正确的做法。可能是因为我来自perl,而且我不习惯python正则表达式。

  • 第一个问题:是否可以使用正则表达式替换匹配字符串的“边框”,并保持内部不变?我想保留\ command {xxx}的内容。

  • 第二个问题:\ r \ n。显然,当我尝试在终端或每个字符串的文件中打印时,我需要确保\ r不被解释为回车符。我试过使用自动逃生,但这不是我需要的。它逃脱了\ n与另一个\,这不是我想要的。

1 个答案:

答案 0 :(得分:0)

回答你的问题,

  • 第一个问题:您可以使用(命名)组
  • 第二个问题:在Python3中,你可以使用r" \ btree"优雅地处理反斜杠。

使用像github.com/alvinwan/TexSoup这样的乳胶解析器,我们可以稍微简化一下代码。我知道OP已经要求使用正则表达式,但如果OP与工具无关,那么解析器就会更强大。

好的功能

我们可以将它抽象为替换函数

def replaceTex(soup, command, replacement):
    for node in soup.find_all(command):
        node.replace(replacement.format(args=node.args))

然后,按以下方式使用此replaceTex函数

>>> soup = TexSoup(r"\section{hello} text \bra{(.)} haha \ket{(.)}lol")
>>> replaceTex('bra', r"|{args[0]}\rangle")
>>> replaceTex('ket', r"\langle{args[0]}|")
>>> soup
\section{hello} text \langle(.)| haha |(.)\ranglelol

演示

这是一个基于TexSoup的独立演示:

>>> import TexSoup
>>> soup = TexSoup(r"\section{hello} text \bra{(.)} haha \ket{(.)}lol")
>>> soup
\section{hello} text \bra{(.)} haha \ket{(.)}lol
>>> soup.ket.replace(r"|{args[0]}\rangle".format(args=soup.ket.args))
>>> soup.bra.replace(r"\langle{args[0]}|".format(args=soup.bra.args))
>>> soup
\section{hello} text \langle(.)| haha |(.)\ranglelol