我有一个字符串。结尾不同,例如index.php?test=1&list=UL
或index.php?list=UL&more=1
。我正在寻找的一件事是&list=
。
我如何匹配它,无论是在字符串的中间还是在结尾?到目前为止,我已经[&|\?]list=.*?([&|$])
,但([&|$])
部分实际上并不起作用;我正在尝试使用它来匹配&
或字符串的结尾,但字符串部分的结尾不起作用,因此此模式与第二个示例匹配,但不匹配第一个示例。
答案 0 :(得分:43)
答案 1 :(得分:1)
[...]
内的任何零宽度断言都失去了零宽度断言的含义。 [\b]
与单词边界不匹配(它与退格符匹配,或者在POSIX中为\
或b
),[$]
与文字$
字符匹配, [^]
是错误,或者如ECMAScript regex风格所示,是任何字符。与\z
,\Z
,\A
锚点相同。
您可以使用以下任意一种模式解决问题:
[&?]list=([^&]*)
[&?]list=(.*?)(?=&|$)
[&?]list=(.*?)(?![^&])
.*?([YOUR_SINGLE_CHAR_DELIMITER(S)]|$)
模式(suggested by João Silva)的效率相当低,因为正则表达式引擎首先检查在懒点模式右边出现的模式,并且只有当它们不匹配时,它才会进行检查”扩展”懒点模式。
在这些情况下,建议使用negated character class(或POSIX讨论中的括号表达式):
[&?]list=([^&]*)
See demo。 详细信息
[&?]
-与&
或?
匹配的正字符类(请注意,字符类中char / char范围之间的关系是OR关系)list=
-子字符串,char序列([^&]*)
-捕获组#1:除*
(&
)以外的零个或更多([^&]
)个字符大多数正则表达式版本(包括从ECMAScript 2018开始的JavaScript)都支持环视,这种构造仅在模式匹配或不匹配时返回true或false。如果期望连续的匹配可能以相同的字符开始和结束,则它们是至关重要的(请参见原始模式,它可以匹配以&
开头和结尾的字符串)。尽管查询字符串中不会出现这种情况,但这是一种常见情况。
在这种情况下,您可以使用两种方法:
(?=[SINGLE_CHAR_DELIMITER(S)]|$)
(?![^SINGLE_CHAR_DELIMITER(S)])
否定超前解决方案效率更高一点,因为它不包含会增加匹配过程复杂性的交替组。 OP解决方案看起来像
[&?]list=(.*?)(?=&|$)
或
[&?]list=(.*?)(?![^&])
请参见this regex demo和another one here。
当然,在尾部定界符为多字符序列的情况下,由于[^yes]
不会否定字符序列,但是类中的字符(即[^yes]
会匹配任何字符字符,但y
,e
和s
)。