在正则表达式中,匹配字符串的结尾或特定字符

Gar*_*ary 32 javascript regex pattern-matching

我有一个字符串.结局是不同的,例如index.php?test=1&list=ULindex.php?list=UL&more=1.我正在寻找的一件事是&list=.

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

Joã*_*lva 51

使用:

/(&|\?)list=.*?(&|$)/
Run Code Online (Sandbox Code Playgroud)

请注意,当您使用括号表达式时,其中的每个字符(有一些例外)将按字面解释.换句话说,[&|$]相匹配的角色 &,|$.

  • 谢谢; 我不知道方括号的“字面解释”部分。很有用!那么,为了使用“|”分隔两个或多个字符,是否需要“()”? (4认同)

Wik*_*żew 13

简而言之

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

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

[&?]list=([^&]*)
[&?]list=(.*?)(?=&|$)
[&?]list=(.*?)(?![^&])
Run Code Online (Sandbox Code Playgroud)

如果您需要检查“绝对”、明确的字符串结尾锚点,您需要记住这是各种正则表达式风格,它用不同的结构表示:

[&?]list=([^&]*)
[&?]list=(.*?)(?=&|$)
[&?]list=(.*?)(?![^&])
Run Code Online (Sandbox Code Playgroud)

字符序列与单个字符或字符串结尾之间的匹配(当前场景)

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

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

[&?]list=([^&]*)
Run Code Online (Sandbox Code Playgroud)

见演示细节

  • [&?]- 匹配&或的正字符类?(注意字符类中字符/字符范围之间的关系是 OR 关系)
  • list= - 一个子字符串,字符序列
  • ([^&]*)-捕获组#1:零个或多个(*)字符以外&[^&]),尽可能多的

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

大多数正则表达式风格(包括从 ECMAScript 2018 开始的 JavaScript)支持环视,仅在模式匹配或不匹配时才返回 true 或 false 的构造。如果预期可能以相同字符开头和结尾的连续匹配项(请参阅原始模式,它可能匹配以 开头和结尾的字符串&),它们是至关重要的。虽然它不是查询字符串中所期望的,但它是一个常见的场景。

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

  • 具有包含正字符类的交替的正前瞻: (?=[SINGLE_CHAR_DELIMITER(S)]|$)
  • 仅负字符类的负前瞻: (?![^SINGLE_CHAR_DELIMITER(S)])

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

[&?]list=(.*?)(?=&|$)
Run Code Online (Sandbox Code Playgroud)

或者

[&?]list=(.*?)(?![^&])
Run Code Online (Sandbox Code Playgroud)

在此处查看此正则表达式演示另一个演示

当然,如果尾随定界符是多字符序列,则只有正向前瞻解决方案才能工作,因为[^yes]它不会否定字符序列,而是否定类内的字符(即[^yes]匹配任何字符,但y,es)。

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