入力文字列を解析し、二重引用符("
)で囲まれた文字列が含まれているかどうかを確認したいと考えています。 バックスラッシュでエスケープされない限り、文字のシーケンス自体には二重引用符を使用することはできません(例:\"
)。エスケープ文字を許可する文字列リテラルをスキャンする方法は?
物事をより複雑にするために、バックスラッシュはそうのように、自分自身をエスケープすることができます:\\
。 2つの(または偶数の)バックスラッシュ(\\"
)で始まる二重引用符はエスケープされません。 さらに悪化させるために、エスケープしない単一のバックスラッシュ(つまり、"
と\
のあとに続かない)が許可されます。
私は、Pythonのre
モジュールとそれを解決しようとしています。ターゲット文字列が走査されるよう
、左から右に
'|'
によって分離RESが試されている: module documentationパイプオペレータA|B
について教えてくれる。 1つのパターンが完全に一致すると、そのブランチが受け入れられます。つまり、A
が一度一致すると、全体的に長い一致が生成されても、B
はそれ以上テストされません。言い換えれば、'|'
オペレータは貪欲ではありません。
しかし、これは私が期待どおりに動作しません:
>>> import re
>>> re.match(r'"(\\[\\"]|[^"])*"', r'"a\"')
<_sre.SRE_Match object; span=(0, 4), match='"a\\"'>
この正規表現のアイデアは、エスケープ文字(\\
または\"
)のための最初のチェックにあり、それが見つからないだ場合にのみ、チェック"
ではない文字(但し、単一の場合もあります)\
です。 これは任意の回数発生することがあり、リテラル"
文字で囲む必要があります。
私は全く一致しない文字列"a\"
を期待するが、どうやらそれはありません。 私はA
の部分とB
の部分をテストしない部分に一致させるために\"
と期待していますが、明らかにそうです。
私は本当にバックトラックは、この非常に場合にはどのように動作するかわかりませんが、それを回避する方法はありますか?
私は初期"
文字の最初のチェック(および入力から削除)場合、それは別のステップで働くだろうと思います。 私は、文字列の内容を取得するには、次の正規表現を使用することができます。
>>> re.match(r'(\\[\\"]|[^"])*', r'a\"')
<_sre.SRE_Match object; span=(0, 3), match='a\\"'>
これは、エスケープ引用符が含まれます。左引用符が残っていないので、私は全体的に、指定された文字列が一致しないことを知っています。
は、私はそのようにそれをしなければならないか、それが単一の正規表現となし、追加の手動チェックでこれを解決することができますか?私の実際のアプリケーションでは、"
- 囲まれた文字列は、より大きなパターンの一部にすぎません。したがって、単一の正規表現ですべてを一度に行う方が簡単だと思います。
同様の質問がありましたが、エスケープされない単一のバックスラッシュが文字列の一部であるとは考えられません。regex to parse string with escaped characters、Parsing for escape characters with a regular expression。
参照:?(?:[^ \\ "] | \\。)*" ' - >' "[^" \\] *(?:\\。[^ "\\] *)* "' –
ありがとう、それは素晴らしい作品!矢印の意味は?代替案の1つは他のものより優れていますか?それらはまったく同等ですか? – Matthias
はい、違いがあります。さて、それはあなたのために働くので、私は答えとしてそれを入れてみましょう。 –