PCRE正则表达式匹配 /x... 但不匹配 /y/x。

3

在配置重定向时,经常会遇到包含相同路径字符串的多个页面。我们曾多次遇到需要重定向的情况:

https://example.com/x...

但不包括:

https://example.com/y/x...

为了匹配/x...,我们使用PCRE正则表达式:

/x.*

我们一直在努力让排除匹配正确;我们先道歉,因为我们的正则表达式有点薄弱,以下是我们的伪代码:
Match all /x... except /y/x...

这是我们认为的结果:
^\/(?!y\/).x.*

在我们的思维中,它会这样解读:

Any query starting with /x..., except starting with /y/x...

提前感谢您,如果有更好的格式建议请随意提出,我们并不是 Stack Overflow 专家。

2个回答

2

您的正则表达式从字符串开头匹配一个斜杠,然后使用负向先行断言来检查接下来的内容不是y/。如果是,那么匹配任何字符,然后是x和0个或多个字符。例如,这将匹配//x///

如果不考虑匹配URL部分,一种方法是使用负面先行断言(?!)来检查右侧是否不包含/y/x,然后匹配任何字符:

^(?!.*/y/x).+

正则表达式演示


谢谢,这是一个有用的起点。你恰好得到了我们缺失的一半,即排除/y/x... 但那也会匹配所有其他查询,比如/z/。这意味着要在正则表达式之前添加吗,以匹配/x/?类似于^(?!./y/x).+x. - beta208
你真聪明,那个方法起作用了:^(?!./y/x)./x.* 你能给我解释一下这段伪代码的含义吗?这样以后用户就不需要复制了,可以学习一下他们可能误解的地方。我理解为它表示所有以排除/y/x的实例开头的查询,除非是以/x...开头的。 - beta208
我认为你需要:^(?!.*/y/x)/x.+ 只匹配路径中包含 /x 的内容。 - Poul Bak
1
@beta208 如果字符串中应该有“/x”,那么这个正则表达式^(?!.*/y/x).*/x.*就可以工作。它会匹配到最后一个“/x”,并在其之后匹配任意字符0次或多次。 - The fourth bird
1
谢谢,那确实有道理。 - beta208

1
您可以使用负回顾断言:


~(?<!/y)/x~

正则表达式演示

(?<!/y)是一个负向后瞻断言,如果在匹配/x之前出现/y,则匹配失败。


我看到这个也匹配并且更短。我想这是理想的解决方案? - beta208
1
是的,您的要求需要使用“向后查找”,而且这个正则表达式比 ^(?!.*/y/x).*/x 更高效,您可以在我提供的正则表达式演示链接中看到它所需的步骤数量。 - anubhava
在我们的系统中,这个字符串没有匹配 "/lunch/",但是只匹配了 "/lunch"。那么正则表达式应该是:~(?<!/y)/x.*。 - beta208
抱歉,我不明白你的意思。你系统上实际使用的正则表达式是什么? - anubhava

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接