引用符を含むことができるパターンに一致する正規表現をどのように作成しますか?
"?(pattern)"?
引用符で始まり、引用符で終わらないパターンが許可されるため、機能しません。
"(pattern)"|(pattern)
機能しますが、繰り返します。パターンを繰り返さずにそれを行うより良い方法はありますか?
引用符を含むことができるパターンに一致する正規表現をどのように作成しますか?
"?(pattern)"?
引用符で始まり、引用符で終わらないパターンが許可されるため、機能しません。
"(pattern)"|(pattern)
機能しますが、繰り返します。パターンを繰り返さずにそれを行うより良い方法はありますか?
後方参照と条件を利用することで、繰り返すことなく解決策を得ることができます:
/^(")?(pattern)(?(1)\1|)$/
一致:
一致しません:
ただし、このパターンはやや複雑です。最初にオプションの引用符を探し、見つかった場合は後方参照 1 に入れます。次に、パターンを検索します。次に、条件付き構文を使用して、「後方参照 1 が再び見つかった場合は一致し、それ以外の場合は一致しません」と言います。パターン全体が固定されている (つまり、行にそれ自体を表示する必要がある) ため、一致しない引用符がキャプチャされません (そうでない場合はpattern
inpattern"
が一致します)。
条件のサポートはエンジンによって異なり、より冗長で反復的な式がより広くサポートされる (そしておそらく理解しやすい) ことに注意してください。
更新:この正規表現のより単純なバージョンは/^(")?(pattern)\1$/
、条件を必要としない になります。これを最初にテストしたとき、使用していたテスターが偽陰性を示したため、それを無視することにしました (おっと!)。
後世と興味のために、条件付きでソリューションを残しておきますが、これはより単純なバージョンであり、さまざまなエンジンで動作する可能性が高くなります (ここで使用されている機能は後方参照のみであり、サポートされていない可能性があります)。
使用している言語によっては、後方参照を使用できるはずです。次のように言います。
(["'])(pattern)\1|^(pattern)$
そうすれば、引用符がないか、両端で同じ引用符を使用する必要があります。
これは、再帰的な正規表現で動作するはずです (正しくなるには時間がかかります)。それまでの間: Perlでは、自己変更正規表現を作成できます。私はそれを学術的な例として残します;-)
my @stuff = ( '"pattern"', 'pattern', 'pattern"', '"pattern' );
foreach (@stuff) {
print "$_ OK\n" if /^
(")?
\w+
(??{defined $1 ? '"' : ''})
$
/x
}
結果:
"pattern" OK
pattern OK