混淆正则表达式匹配 "question marks"

Confusion with regex matching "question marks"

我有几个 URL,如下所示:

www.xyz.com/search/example?x=123
www.xyz.com/search/example

我想检索 "the string between last slash and question mark (if exists)" 即,对于上述示例,我想检索 "example"。为此,我使用了下面的正则表达式,但它不起作用。有人可以解释一下为什么它不起作用。我检查了“https://regex101.com/”的解释,但他们的解释似乎与我的想法相符,但事实并非如此。匹配问号时出现问题,“\?*”无法匹配一个或多个问号。

.*\/(.*?)\?*.*

仅供参考,我可以编写以下正则表达式来处理我的用例:

.*\/((?:[^?])*)

我怀疑为什么下面的正则表达式不起作用:

.*\/(.*?)\?*.*

使用基于正前瞻的正则表达式。

\/([^\/?]*)(?=[^\/]*$)

DEMO

(?<=\/)[^\/?]*(?=[^\/]*$)

.*\/(.*?)(?:\?|$)

您的最后一个正则表达式将不起作用,因为 \?* 匹配零个或多个 ?。让你的正则表达式匹配 ? 如果存在或者让它匹配直到行结束。 (?:\?|$) 期望匹配项旁边有一个 ? 或行尾。

您可以使用这个正则表达式:

.*\/([^\?]+)

匹配 "all non-question-mark characters in a string with minimum length 1"。转义 ? (\?) 很重要,因为它是 0 or 1 的保留字符。请注意,这需要在最后一个 / 之后至少有一个字符(i.e. www.xyz.com/search/example/? 会导致 example/)。如果应该避免这种情况,请将 + 替换为 * 匹配不包含 ? 的全长字符串:

.*\/([^\?]*)

关于您的问题,为什么 .*\/(.*?)\?*.* 不起作用。 (.*?) 部分匹配任何长度(包括 0 长度)的任何字符 (.) 的所有字符串,无论是否存在 (?),所以基本上它匹配空字符串。尾部 \?*.* 匹配所有可能以或不以任意数量的 ? 开头的字符串,所以它基本上匹配所有字符串,相当于 .*