65

文字列があります。index.php?test=1&list=ULまたはなど、末尾が異なりindex.php?list=UL&more=1ます。私が探しているのは&list=

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

4

2 に答える 2

88

使用する:

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

角かっこ式を使用する場合、その中のすべての文字(一部の例外を除く)は文字通りに解釈されることに注意してください。つまり、、、、およびの文字[&|$]一致します。 &|$

于 2012-08-23T00:49:30.643 に答える
15

要するに

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

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

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

「絶対的な」明確な文字列エンドアンカーをチェックする必要がある場合は、それがさまざまな正規表現フレーバーであり、さまざまな構成で表現されていることを覚えておく必要があります。

[&?]list=(.*?)(?=&|$)  - OK for ECMA regex (JavaScript, default C++ `std::regex`)
[&?]list=(.*?)(?=&|\z) - OK for .NET, Go, Onigmo (Ruby), Perl, PCRE (PHP, base R), Boost, ICU (R `stringr`), Java/Andorid
[&?]list=(.*?)(?=&|\Z) - OK for Python

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

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

このような場合、否定文字クラス(またはPOSIXトークでは角かっこ式)を使用することをお勧めします。

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

デモを参照してください詳細

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

末尾の単一文字区切り文字の存在を、それまたは文字列の終わりを返さずにチェックします

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

その場合、2つのアプローチを使用できます。

  • ポジティブなキャラクタークラスを含む交互のポジティブな先読み:(?=[SINGLE_CHAR_DELIMITER(S)]|$)
  • ネガティブな文字クラスだけのネガティブな先読み:(?![^SINGLE_CHAR_DELIMITER(S)])

ネガティブ先読みソリューションは、マッチング手順を複雑にする交代群を含まないため、もう少し効率的です。OPソリューションは次のようになります

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

また

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

この正規表現のデモ別のデモをここで参照してください。

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

于 2018-07-02T11:08:47.140 に答える