In short
任何在
[...]
内的零宽度断言都会失去零宽度断言的意义。
[\b]
不匹配单词边界(它匹配退格,或者,在POSIX中,匹配
\
或
b
)。替换代码4】匹配一个字面的
$
字符,
[^]
是一个错误,或者像ECMAScript regex风味一样,是任何字符。与
\z
、
\Z
、
\A
的锚点相同。
你可以使用以下任何一种模式来解决这个问题。
[&?]list=([^&]*)
[&?]list=(.*?)(?=&|$)
[&?]list=(.*?)(?![^&])
如果你需要检查 "绝对 "的、不含糊的字符串末端锚,你需要记住,在不同的regex风味中,它用不同的结构来表达。
[&?]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
在字符序列和单个字符或字符串结尾之间进行匹配(当前情况下)
The .*?([YOUR_SINGLE_CHAR_DELIMITER(S)]|$)
pattern (由João Silva建议)是相当低效的,因为regex引擎首先检查出现在lazy dot模式右边的模式,只有当它们不匹配时才 "扩展 "lazy dot模式。
在这些情况下,建议使用被否定的字符类 (or 括号内表达in the POSIX talk)。
[&?]list=([^&]*)
See demo. 详情
[&?]
- a positive character class matching either &
or ?
(note the relationships between chars/char ranges in a character class are OR relationships)
list=
- a substring, char sequence
([^&]*)
- Capturing group #1: zero or more (*
) chars other than &
([^&]
), as many as possible
检查尾部单字符定界符是否存在,但不返回,也不返回字符串的末尾。
大多数regex风味(包括从ECMAScript 2018开始的JavaScript)支持lookarounds,这些结构只在模式匹配或不匹配时返回真或假。它们对于可能以相同字符开始和结束的连续匹配是至关重要的(参见原始模式,它可能匹配以&
开始和结束的字符串)。虽然在查询字符串中不需要这样做,但这是一种常见的情况。
在这种情况下,你可以使用两种方法。
A positive lookahead with an alternation containing positive character class: (?=[SINGLE_CHAR_DELIMITER(S)]|$)
A negative lookahead with just a negative character class: (?![^SINGLE_CHAR_DELIMITER(S)])
负向查找解决方案的效率更高一些,因为它不包含增加匹配程序复杂性的交替组。负数解决方案看起来像
[&?]list=(.*?)(?=&|$)