我有绳子。结尾是不同的,例如index.php?test=1&list=ULindex.php?list=UL&more=1。我要寻找的一件事是&list=

我该如何匹配它,无论是在字符串的中间还是在字符串的末尾?到目前为止,我已经有了[&|\?]list=.*?([&|$]),但是([&|$])的部分实际上并没有工作。我正在尝试使用它来匹配&或字符串的末尾,但是字符串部分的末尾不起作用,因此此模式匹配第二个示例,但不匹配第一个示例。

#1 楼

使用:

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


请注意,当使用方括号表达式时,其中的每个字符(有些例外)将按字面意义进行解释。换句话说,[&|$]与字符&|$匹配。

评论


谢谢;我不知道方括号中的“按字面解释”部分。很有用!所以为了使用|分隔两个或多个字符,()是否必需?

–加里
2012年8月23日在0:57



是的,确实,您需要对备选方案进行分组(())。

–JoãoSilva
2012年8月23日在1:05

@DrazenBjelovuk您可能的意思是'SomeText / blahblah'.match(/ Some([^ \ /] *)/)[1](输出文本)。看到我的答案,每个解决方案都包含一个捕获组,该捕获组捕获通常在返回匹配项后作为第一个组通常需要的子匹配项。

–WiktorStribiżew
18年7月4日在20:20



@WiktorStribiżew在Hindsight中,看来我的意思是string.match(/ Some。*?(\ / | $)/)[0];。不知道为什么在这一点上,虽然大声笑。

– Drazen Bjelovuk
18年7月4日在20:33

@DrazenBjelovuk是的,惰性点匹配将匹配后续子模式的最左出现。

–WiktorStribiżew
18年7月4日在20:34



#2 楼

简而言之

[...]内部的任何零宽度断言都失去了零宽度断言的含义。 [\b]与单词边界不匹配(它与退格符匹配,或者在POSIX中为\b),[$]与文字$字符匹配,[^]是错误,或者像在ECMAScript regex风格中一样,是任何字符。与\z\Z\A锚点相同。

您可以使用以下任意一种模式解决问题:

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


字符之间的匹配序列和单个字符或字符串结尾(当前情况)

.*?([YOUR_SINGLE_CHAR_DELIMITER(S)]|$)模式(由JoãoSilva建议)效率不高,因为正则表达式引擎会检查出现在惰性点右侧的模式模式,并且只有当它们不匹配时,才“扩展”惰性点模式。

在这种情况下,建议使用否定的字符类(或POSIX对话中的方括号表达式):

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


请参阅演示。详细信息



[&?]-与&?匹配的正字符类(请注意,字符类中char / char范围之间的关系为OR关系)

list=-子字符串,char序列

([^&]*)-捕获组#1:除*&)以外的零个或多个([^&])字符,并尽可能多地

检查尾随的单个char分隔符是否存在而不返回它或字符串末尾

大多数正则表达式类型(包括以ECMAScript 2018开头的JavaScript)都支持环视,只有在模式匹配或匹配的情况下才返回true或false的构造不。如果连续匹配可能以相同的char开头和结尾,则它们是至关重要的(请参阅原始模式,它可能匹配以&开头和结尾的字符串)。尽管查询字符串中不希望出现这种情况,但这是一种常见情况。

在这种情况下,您可以使用两种方法:


带有正字符类的正向前瞻性替换:(?=[SINGLE_CHAR_DELIMITER(S)]|$)

带有负字符的负向前瞻性class:(?![^SINGLE_CHAR_DELIMITER(S)])


否定的前瞻性解决方案效率更高,因为它不包含会增加匹配过程复杂性的替代组。 OP解决方案看起来像

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




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


请参见此regex演示和此处的另一个演示。

某些情况下,如果尾部定界符是多字符序列,则只能使用正向超前解决方案,因为[^yes]不会否定一个字符序列,但是该类内部的字符(即[^yes]匹配任何字符,但yes)。

评论


这应该是公认的答案,恕我直言,否定字符解决方案正是所需的,而且更通用(即可能适用于其他搜索类似问题的用户)。

– TrustyPatches
12月7日13:05