web-dev-qa-db-ja.com

二重引用符付きの文字列をエスケープされた二重引用符付き文字と一致させるにはどうすればよいですか?

文字列を照合するには、Perlの正規表現が必要です。二重引用符で囲まれた文字列のみを想定しています。\ "は文字列の末尾ではなく、文字どおりの引用文字であり、\は文字どおりのバックスラッシュ文字であり、引用文字をエスケープしてはなりません。明確でない場合は、例:

"\""    # string is 1 character long, contains dobule quote
"\\"    # string is 1 character long, contains backslash
"\\\""  # string is 2 characters long, contains backslash and double quote
"\\\\"  # string is 2 characters long, contains two backslashes

これらの4つの可能性すべて、およびこれらの可能性のその他すべての単純なバリエーションを有効な文字列として認識できる正規表現が必要です。私が今持っているのは:

/".*[^\\]"/

しかし、それは正しくありません-最初のもの以外のどれにも一致しません。誰もがこれを処理する方法について正しい方向に私にプッシュを与えることができますか?

31
Chris Lutz

これはどう?

/"([^\\"]|\\\\|\\")*"/

スラッシュまたは引用符ではない0個以上の文字に一致しますOR 2つのスラッシュORスラッシュと引用符

26
Cal

/"(?:[^\\"]|\\.)*"/

これはCalの回答とほとんど同じですが、\nなどのエスケープコードを含む文字列を照合するという利点があります。

?:文字は、含まれている式が後方参照として保存されるのを防ぐためにありますが、削除することができます。

41
j_random_hacker

一般的なソリューション(すべてのバックスラッシュ文字に一致):

/ \A "               # Start of string and opening quote
  (?:                #  Start group
    [^\\"]           #   Anything but a backslash or a quote
    |                #  or
    \\.              #   Backslash and anything
  )*                 # End of group
  " \z               # Closing quote and end of string
  /xms
9
Leon Timmermans

Text :: Balanced を参照してください。ホイールを再発明するよりも優れています。使用する gen_delimited_pat結果パターンを確認し、それから学習します。

これは非常に簡単な方法です:

/"(?:\\?.)*?"/

このような正規表現を文字列に埋め込んでバックスラッシュを2倍にするかどうかを覚えておいてください。

1
Boann

RegExp :: Common は、もう1つ知っておくと便利なツールです。多くの一般的なケースの正規表現が含まれ、引用符付きの文字列が含まれています。

use Regexp::Common;

my $str = '" this is a \" quoted string"';
if ($str =~ $RE{quoted}) {
  # do something
}
1
Rob Van Dam

次のコードを試してください:(\".+")

0
user2877627