3

プレーンテキストを入力として受け取り、LaTeXコードを出力として生成するPythonスクリプトを書いています。ある時点で、スクリプトは、、、、など、TeXで特別な意味を持つすべての文字を引用符で囲む必要があり%ます。&\

これは思ったより難しいです。現在私はこれを持っています:

def ltx_quote(s):
    s = re.sub(r'[\\]', r'\\textbackslash{}', s)
    # s = re.sub(r'[{]', r'\\{{}', s)
    # s = re.sub(r'[}]', r'\\}{}', s)
    s = re.sub(r'[&]', r'\\&{}', s)
    s = re.sub(r'[$]', r'\\${}', s)
    s = re.sub(r'[%]', r'\\%{}', s)
    s = re.sub(r'[_]', r'\\_{}', s)
    s = re.sub(r'[\^]', r'\\^{}', s)
    s = re.sub(r'[~]', r'\\~{}', s)
    s = re.sub(r'[|]', r'\\textbar{}', s)
    s = re.sub(r'[#]', r'\\#{}', s)
    s = re.sub(r'[<]', r'\\textless{}', s)
    s = re.sub(r'[>]', r'\\textgreater{}', s)
    return s

問題は、{and}文字です。これは、以前の置換(\-> \textbackslash{})によって生成される可能性があるためです。この場合、置換すべきではありません。解決策はすべての置換を1つのステップで行うことだと思いますが、その方法がわかりません。

4

1 に答える 1

3

おそらく、文書化されていないre.Scannerを使用してみてください:

import re
scanner = re.Scanner([
    (r"[\\]", r'\\textbackslash{}'),
    (r"[{]", r'\\{{}'),
    (r"[}]", r'\\}{}'), 
    (r".", lambda s, t: t)
])

tokens, remainder = scanner.scan("\\foo\\{bar}")
print(''.join(tokens))

収量

\\textbackslash{}foo\\textbackslash{}\\{{}bar\\}{}

投稿したコードとは異なり、ソースコードを見ると、re.Scanner.scanは文字列を1回だけ通過します。試合が行われると、最後の試合が終了したところから次の試合が始まります。

の最初の引数re.Scannerlexicon---2タプルのリストです。各2タプルは、正規表現パターンとアクションです。アクションは、文字列、呼び出し可能(関数)、またはNone(アクションなし)の場合があります。

パターンはすべて1つの複合パターンにコンパイルされます。したがって、レキシコンにパターンがリストされている順序が重要です。一致する最初のパターンが勝ちます。

一致した場合、アクションは呼び出し可能であれば呼び出され、文字列の場合は単に返されます。戻り値はリストに収集されますtokens

于 2013-02-14T13:04:31.563 に答える