web-dev-qa-db-ja.com

正規表現では、文字列の末尾または特定の文字に一致します

紐があります。 _index.php?test=1&list=UL_や_index.php?list=UL&more=1_など、終わりが異なります。私が探しているのは、_&list=_だけです。

文字列の途中であっても、最後であっても、どのように一致させることができますか?これまでのところ[&|\?]list=.*?([&|$])はありますが、_([&|$])_の部分は実際には機能しません。これを使用して_&_または文字列の末尾を照合しようとしていますが、文字列の末尾の部分は機能しないため、このパターンは2番目の例と一致しますが、最初の例とは一致しません。

34
Gary

使用する:

/(&|\?)list=.*?(&|$)/

大括弧式を使用すると、その中のすべての文字( some 例外を含む)は文字どおりに解釈されることに注意してください。言い換えると、 [&|$]文字に一致します&|$

53
João Silva

要するに

[...]内のゼロ幅アサーションは、ゼロ幅アサーションの意味を失います。 [\b]はWordの境界と一致しません(バックスペース、またはPOSIXでは\またはbと一致します)。[$]はリテラル$ charと一致します。[^]はエラーであるか、ECMAScript正規表現フレーバーのように任意の文字です。 \z\Z\Aアンカーと同じです。

以下のパターンのいずれかを使用して問題を解決できます。

[&?]list=([^&]*)
[&?]list=(.*?)(?=&|$)
[&?]list=(.*?)(?![^&])

文字シーケンスと単一の文字または文字列の終わりとのマッチング(現在のシナリオ)

.*?([YOUR_SINGLE_CHAR_DELIMITER(S)]|$)パターン( JoãoSilvaによって提案 )は、正規表現エンジンが最初に遅延ドットパターンの右側に表示されるパターンをチェックするため、効率的ではないため、かなり非効率的です一致しないと、遅延ドットパターンが「拡張」されます。

これらの場合、POSIXトークでは negated character class (orbracket expressionを使用することをお勧めします):

[&?]list=([^&]*)

デモを参照詳細

  • [&?]-&または?のいずれかに一致する正の文字クラス(文字クラス内のchars/char範囲間の関係はOR関係であることに注意)
  • list=-部分文字列、文字シーケンス
  • ([^&]*)-キャプチャグループ#1:*&)以外の0個以上の([^&])文字、できるだけ多く

文字列の終わりまたは文字列の終わりを返さずに、末尾の単一文字区切り文字の存在を確認する

ほとんどの正規表現フレーバー(ECMAScript 2018で始まるJavaScriptを含む)は、パターンが一致するかどうかにかかわらずtrueまたはfalseを返す構成要素であるルックアラウンドをサポートしています。同じ文字で開始および終了する可能性のある連続した一致が期待される場合、これらは重要です(元のパターンを参照してください。これは、&で開始および終了する文字列に一致する場合があります)。クエリ文字列では想定されていませんが、一般的なシナリオです。

その場合、2つの方法を使用できます。

  • 正の文字クラスを含む交互の正の先読み:(?=[SINGLE_CHAR_DELIMITER(S)]|$)
  • 負の文字クラスのみの負の先読み:(?![^SINGLE_CHAR_DELIMITER(S)])

負の先読みソリューションは、照合手順を複雑にする代替グループを含まないため、少し効率的です。 OPソリューションは次のようになります

[&?]list=(.*?)(?=&|$)

または

[&?]list=(.*?)(?![^&])

この正規表現のデモ および ここに別のデモ を参照してください。

確かに、末尾の区切り文字が複数文字シーケンスである場合、[^yes]は文字のシーケンスを否定しないため、正の先読みソリューションのみが機能しますが、クラス内の文字(つまり、[^yes]は、yeおよびs以外の任意の文字に一致します)。

2