正则表达式匹配不能按预期工作

时间:2013-07-25 09:10:21

标签: php regex

我正在尝试匹配以“string”开头而不是以[[number]

结尾的每个字符串(url)

所以我做了这个正则表达式

string/?.*(?!-[0-9]*)

根据我的理解,它应该被理解为:

  

匹配以“string”开头的每个字符串,后面可能有一个'/'   它,有任何字符串后不包括' - '后跟任何   数字或数字。

这是我的测试字符串

string/kkk/aaa/sss/ddd-123
string/kkk/aaa/sss/ddd
string/kkk/aaa/sss
string/kkk/aaa
string/kkk
string/
string/kkk/
string/kkk/aaa/
string/74002

正则表达式只是匹配所有内容,无论如何。

有人能告诉我哪里出错了吗?

3 个答案:

答案 0 :(得分:2)

在你的表达中,你已经在前瞻之前添加了.*

这意味着*将跳过与.匹配的所有可用字符,然后再进行下一步 - 这本质上就是一切,因此您的表达式匹配所有内容。当您想要在模式之后返回所有内容时,通常会使用此方法。

您需要将.*移至前瞻语句或使用非贪婪版本。

尝试类似

的内容
^string/?(?!.+?-\d+$).*

以上内容将匹配所有不以-和数字结尾的字符串。它还将返回匹配模式的实例的整个字符串。我在这里使用了非贪婪的.+?来避免混淆以及添加^开头和$行选择器的结尾。如果模式成功,.*将匹配所有字符。

答案 1 :(得分:0)

试试这个:

$str  = "string/kkk/aaa/sss/ddd123";
echo preg_match("/^string\/(?!.*-\d+$)/",$str);

答案 2 :(得分:0)

您的问题是您不要强制正则表达式匹配整个字符串。

例如,走这一行:

string/kkk/aaa/sss/ddd-123

在这种情况下,.*只会匹配string/之后的所有内容,包括-123。非贪婪的匹配将匹配除d-123之外的所有内容。在任何一种情况下,它都成功地找不到在否定前瞻中给出的内容。

你必须强制正则表达式匹配字符串end($)(可能还有字符串start(^)):

^string/?.*(?!-[0-9]*)$