首先,我认为您的正则表达式需要一些修复。让我们看看你有什么:
test.com(\/\??index_.*.php\??(.*)|\/\?(.*)|\/|)+(\s)*(?!.)
第二种选择已经处理了您?
在开头使用 optional 的情况:index...
test.com(\/index_.*.php\??(.*)|\/\?(.*)|\/|)+(\s)*(?!.)
现在你可能只希望第一个(.*)
被允许,如果之前确实有一个文字?
。否则你会匹配test.com/index_fb2.phpanystringhereandyouprobablydon'twantthat
。所以移动相应的可选标记:
test.com(\/index_.*.php(\?(.*))?|\/\?(.*)|\/|)+(\s)*(?!.)
现在.*
尽可能多地消耗任何角色。此外,.
前面的php
消耗任何字符。这意味着您将同时允许test.com/index_fb2php
和test.com/index_fb2.html?someparam=php
。让我们把它变成文字.
并且只允许非问号字符:
test.com(\/index_[^?]*\.php(\?(.*))?|\/\?(.*)|\/|)+(\s)*(?!.)
现在第一个、第二个和第三个选项可以合并为一个,如果我们也将文件名设为可选:
test.com(\/(index_[^?]*\.php)?(\?(.*))?|)+(\s)*(?!.)
最后,+
可以删除,因为(.*)
内部已经可以处理所有可能的重复。也(something|)
与(something)?
:
test.com(\/(index_[^?]*\.php)?(\?(.*))?)?(\s)*(?!.)
看到您的输入示例,这似乎更接近您实际想要匹配的内容。
然后回答你的问题。什么(?!.)
取决于您是否使用singleline
模式。如果你这样做了,它就断言你已经到达了字符串的末尾。在这种情况下,您可以简单地将其替换为\Z
,它始终匹配字符串的结尾。如果你不这样做,那么它断言你已经到了一行的末尾。在这种情况下,您可以使用$
,但您还需要使用多行模式,以便也$
匹配行尾。
因此,如果您使用singleline
模式(这可能意味着每个字符串只有一个 URL),请使用以下命令:
test.com(\/(index_[^?]*\.php)?(\?(.*))?)?(\s)*\Z
如果您不使用singleline
模式(这可能意味着您可以在自己的行中有多个 URL),您还应该使用multiline
模式和这种锚点:
test.com(\/(index_[^?]*\.php)?(\?(.*))?)?(\s)*$