3

コンパイラークラスでは、Pythonでのプログラミングを楽しんでいるので、Pythonでコンパイラーを作成することにしましたが、文字の印刷方法に興味深い問題が発生しました。私が書いているレクサーでは、フォームフィード文字とバックスペース文字を含む文字列を非常に特殊な方法でstdoutに出力する必要があります。二重引用符で囲み、それぞれ\fと\bとして出力します。私が得た最も近いもの:

print("{0!r}".format("\b\f"))

これは

'\x08\x0c'

一重引用符とutf8コーディングに注意してください。私が関わっている他の2つのキャラクターと同じコマンドは、ほとんど機能します。

print("{0!r}".format("\n\t"))

与える:

'\n\t'

明確にするために、仕様に準拠する必要がある結果(引用符を含む)は次のとおりです。

"\b\f"

\bと\fを見つけて、それらを「\b」と「\f」に置き換えるなどの単純なアプローチは機能しないようです...「\」はPythonがバックスラッシュを出力する方法にすぎないため、予想どおり、「\ b\f」だけを取得します。

さまざまな文字列エンコーディングで遊んでも役に立たないようです。カスタムstring.Formatterを作成する必要があると結論付けましたが、見逃した別のアプローチがあるかどうか疑問に思いました。

編集:すべての答えをありがとう。でも、質問をするのはそれほど良い仕事ではなかったと思います。根本的な問題は、リテラルの改行を「\ n」として表示し、リテラルのタブを「\ t」として表示するため、文字列をrawとしてフォーマットしていることです。ただし、生のフォーマットを使用して文字列を印刷するように移動すると、以下のすべての回答が示すように、「\b」と「\f」を印刷できなくなります。

今夜確認しますが、これらの回答に基づいて、出力を通常どおりにフォーマットし、すべてのリテラル「\ n」、「\ t」、「\ b」、および「必要に応じてそれらを出力するエスケープシーケンスを持つ\f"文字。私はまだstring.Formatterの使用を避けたいと思っています。

EDIT2:私が使用する最後のアプローチは、非生の文字列フォーマットを使用することです。非抽象バージョンは次のようになります。

print('"{0!s}"'.format(a.replace("\b", "\\b").replace("\t", "\\t").replace("\f", "\\f").replace("\n","\\n")))
4

3 に答える 3

5

生の文字列を使用します。

>>> print(r'\b')
    \b
于 2012-05-09T16:11:43.983 に答える
3
print("{0!r}".format("\b\f".replace("\b", "\\b").replace("\f", "\\f")))

または、よりきれいに:

def escape_bs_and_ff(s):
    return s.replace("\b", "\\b").replace("\f", "\\f")

print("{0!r}".format(escape_bs_and_ff("\b\f"))
于 2012-05-09T16:16:34.190 に答える
0
>>> print(r'"\b\f"')
"\b\f"

は生の文字列または逐語的な文字列を示します。これは、改行rなどを解析しようとする代わりに、文字通り文字列を作成することを意味します。\n\n

于 2012-05-09T16:18:18.927 に答える