要するに
内部[...]
のゼロ幅アサーションは、ゼロ幅アサーションの意味を失います。[\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]
以外の任意の文字と一致します)。y
e
s