我有一个字符串。结尾不同,例如index.php?test=1&list=UL
or index.php?list=UL&more=1
。我正在寻找的一件事是&list=
。
我如何匹配它,无论是在字符串的中间还是在末尾?到目前为止,我得到了[&|\?]list=.*?([&|$])
,但该([&|$])
部分实际上不起作用;我正在尝试使用它来匹配字符串的任何一个&
或结尾,但字符串部分的结尾不起作用,因此此模式与第二个示例匹配,但与第一个不匹配。
我有一个字符串。结尾不同,例如index.php?test=1&list=UL
or index.php?list=UL&more=1
。我正在寻找的一件事是&list=
。
我如何匹配它,无论是在字符串的中间还是在末尾?到目前为止,我得到了[&|\?]list=.*?([&|$])
,但该([&|$])
部分实际上不起作用;我正在尝试使用它来匹配字符串的任何一个&
或结尾,但字符串部分的结尾不起作用,因此此模式与第二个示例匹配,但与第一个不匹配。
简而言之
内部的任何零宽度断言[...]
都失去了零宽度断言的含义。[\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
字符序列与单个字符或字符串结尾之间的匹配(当前场景)
该.*?([YOUR_SINGLE_CHAR_DELIMITER(S)]|$)
模式(由 João Silva 建议)效率相当低,因为正则表达式引擎首先检查出现在惰性点模式右侧的模式,并且只有当它们不匹配时,它才会“扩展”惰性点模式。
在这些情况下,建议使用否定字符类(或POSIX 谈话中的括号表达式):
[&?]list=([^&]*)
见演示。细节
[&?]
&
- 匹配或匹配的正字符类?
(注意字符类中字符/字符范围之间的关系是 OR 关系)list=
- 一个子字符串,字符序列([^&]*)
- 捕获组 #1:除 ( ) 之外的零个或多个 ( )*
字符,尽可能多&
[^&]
检查尾随单个字符分隔符的存在而不返回它或字符串的结尾
大多数正则表达式风格(包括从 ECMAScript 2018 开始的 JavaScript)支持环视,即仅在模式匹配或不匹配时才返回 true 或 false 的构造。在预期可能以相同字符开头和结尾的连续匹配时,它们至关重要(请参阅原始模式,它可能匹配以 开头和结尾的字符串&
)。尽管在查询字符串中不应该出现这种情况,但这是一种常见的情况。
在这种情况下,您可以使用两种方法:
(?=[SINGLE_CHAR_DELIMITER(S)]|$)
(?![^SINGLE_CHAR_DELIMITER(S)])
负前瞻解决方案效率更高一些,因为它不包含增加匹配过程复杂性的交替组。OP 解决方案看起来像
[&?]list=(.*?)(?=&|$)
或者
[&?]list=(.*?)(?![^&])
当然,如果尾随定界符是多字符序列,则只有肯定的前瞻解决方案才会起作用,因为[^yes]
它不会否定字符序列,而是会否定类中的字符(即[^yes]
匹配除y
,e
和之外的任何字符s
)。