17

Pythonの正規表現と後方参照を使用して文字列のエスケープ解除を実装しようとしていますが、うまく機能しないようです。それは私が間違っていることだと確信していますが、私は何を理解することができません...

>>> import re
>>> mystring = r"This is \n a test \r"
>>> p = re.compile( "\\\\(\\S)" )
>>> p.sub( "\\1", mystring )
'This is n a test r'
>>> p.sub( "\\\\\\1", mystring )
'This is \\n a test \\r'
>>> p.sub( "\\\\1", mystring )
'This is \\1 a test \\1'

\\[char]を\[char]に置き換えたいのですが、Pythonの後方参照は、これまでに使用した他のすべての実装と同じルールに従っていないようです。誰かが光を当てることができますか?

4

5 に答える 5

10

それはアンダースの2番目の例がしていることではありませんか?

2.5には、string-escape適用できるエンコーディングもあります。

>>> mystring = r"This is \n a test \r"
>>> mystring.decode('string-escape')
'This is \n a test \r'
>>> print mystring.decode('string-escape')
This is 
 a test 
>>> 
于 2008-08-17T21:36:32.693 に答える
3

r を忘れたか、バックスラッシュの数え方を間違えたのではないかと思います...

"\\n" == r"\n"

>>> import re
>>> mystring = r"This is \\n a test \\r"
>>> p = re.compile( r"[\\][\\](.)" )
>>> print p.sub( r"\\\1", mystring )
This is \n a test \r
>>>

これは、私が理解した場合、要求されたものです。

より一般的なリクエストは次のとおりだと思います。

>>> d = {'n':'\n', 'r':'\r', 'f':'\f'}
>>> p = re.compile(r"[\\]([nrfv])")
>>> print p.sub(lambda mo: d[mo.group(1)], mystring)
This is \
 a test \
>>>

興味のある学生は、Ken Thompson のReflections on Trusting Trustも読む必要があります。ここで、主人公は同様の例を使用して、機械語コードから自分でブートストラップしていないコンパイラーを信頼することの危険性を説明しています。

于 2008-08-17T19:01:02.990 に答える
1

アイデアは、エスケープされた文字列を読み取り、それをエスケープ解除することです (Python には特に欠けている機能であり、そもそも正規表現に頼る必要はありません)。残念ながら、私はバックスラッシュにだまされていません...

別の説明的な例:

>>> mystring = r"This is \n ridiculous"
>>> print mystring
This is \n ridiculous
>>> p = re.compile( r"\\(\S)" )
>>> print p.sub( 'bloody', mystring )
This is bloody ridiculous
>>> print p.sub( r'\1', mystring )
This is n ridiculous
>>> print p.sub( r'\\1', mystring )
This is \1 ridiculous
>>> print p.sub( r'\\\1', mystring )
This is \n ridiculous

私が印刷したいのは

This is 
ridiculous
于 2008-08-17T19:40:49.820 に答える
0

マーク; 彼の2番目の例では、最初にすべてのエスケープ文字を配列にスローする必要があります。これにより、エスケープシーケンスが配列に含まれていない場合、KeyErrorが生成されます。提供された3文字以外では停止し(\ va tryを指定)、文字列をエスケープ解除する(またはグローバル配列を保持する)たびに可能なすべてのエスケープシーケンスを列挙することは、非常に悪い解決策です。PHPと同様に、この状況ではまったく不要な、preg_replace_callback()の代わりにラムダを使用します。preg_replace()

私がそれについてディックとして外れているならば、すみません、私はPythonに完全にイライラしています。これは、私が今まで使用した他のすべての正規表現エンジンでサポートされており、なぜこれが機能しないのか理解できません。

返信ありがとうございます。string.decode('string-escape')関数はまさに私が最初に探していたものです。誰かが正規表現の後方参照の問題に対する一般的な解決策を持っている場合は、それを投稿してください。私もそれを答えとして受け入れます。

于 2008-08-17T21:55:54.167 に答える
0

Python の結果文字列の表現にだまされています。Python 式:

'This is \\n a test \\r'

文字列を表します

This is \n a test \r

これはあなたが望んでいたことだと思います。各 p.sub() 呼び出しの前に 'print' を追加して、文字列の Python 表現ではなく、返された実際の文字列を出力してみてください。

>>> mystring = r"This is \n a test \r"
>>> mystring
'This is \\n a test \\r'
>>> print mystring
This is \n a test \r
于 2008-08-17T19:26:33.250 に答える