Php preg_match()行为奇怪?

Php preg_match()行为奇怪?,php,regex,Php,Regex,我想根据url比较两个字符串: $reg1 = "/(^(((www\.))|(?!(www\.)))domain\.com\/paramsindex\/([a-z]+)\/([a-z]+)\/((([a-z0-9]+)(\-[a-z0-9]+){0,})(\/([a-z0-9]+)(\-[a-z0-9]+){0,}){0,})|()\/?$)/"; $reg2 = "/(^(((www\.))|(?!(www\.)))domain\.com\/paramsassoc\/([a-z]+)\/([

我想根据url比较两个字符串:

$reg1 = "/(^(((www\.))|(?!(www\.)))domain\.com\/paramsindex\/([a-z]+)\/([a-z]+)\/((([a-z0-9]+)(\-[a-z0-9]+){0,})(\/([a-z0-9]+)(\-[a-z0-9]+){0,}){0,})|()\/?$)/";
$reg2 = "/(^(((www\.))|(?!(www\.)))domain\.com\/paramsassoc\/([a-z]+)\/([a-z]+)\/((([a-z0-9]+)(\-[a-z0-9]+){0,})(\/([a-z0-9]+)(\-[a-z0-9]+){0,}){0,})|()\/?$)/";
$uri  = "www.domain.com/paramsindex/cont/meth/par1/par2/par3/";

$r1 = preg_match($reg1, $uri);
echo "<p>First regex returned: {$r1}</p>";

$r2 = preg_match($reg2, $uri);
echo "<p>Second regex returned: {$r2}</p>";
vs

然而,PHP preg_match对它们都返回1。 现在你会说这是一个很长的正则表达式,为什么要使用它。问题是我可以建立更短的正则表达式,但它是建立在飞行和。。。你需要这样。 而让我烦恼的是,在红细胞正则表达式中,它本该起作用。 在测试它们时,我使用的是Rubular,现在我发现它不起作用了。我知道Rubular是Ruby regex编辑器,但我认为它应该是一样的:(

红细胞试验:


这里有什么问题?我应该如何在PHP中编写正则表达式,以便
preg_match
能够看到差异?并且正则表达式应该与我已经编写的正则表达式非常接近,是否有一些简单的解决方法?我忽略了一些问题?

这种行为是设计的,当找到匹配项时,preg_match返回1。如果要捕获匹配项,请e在以下位置匹配参数:

编辑:例如

$matches = array();
$r2 = preg_match($reg2, $uri, $matches);
echo "<p>Second regex returned: ";
print_r($matches);
echo "</p>";
$matches=array();
$r2=预匹配($reg2,$uri,$matches);
echo“返回的第二个正则表达式:”;
打印(匹配项);
回声“

”;
我将把以上这些留给我自己的愚蠢记录,因为我没有回答正确的问题


在正则表达式的末尾有
|()\/?$)/
,这将使正则表达式匹配以斜杠结尾的URL。把它拿出来,看起来你在我的测试中是金黄色的。

这种行为是经过设计的,当找到匹配项时,preg\u match返回1。如果要捕获匹配项,请参阅以下位置的matches参数:

编辑:例如

$matches = array();
$r2 = preg_match($reg2, $uri, $matches);
echo "<p>Second regex returned: ";
print_r($matches);
echo "</p>";
$matches=array();
$r2=预匹配($reg2,$uri,$matches);
echo“返回的第二个正则表达式:”;
打印(匹配项);
回声“

”;
我将把以上这些留给我自己的愚蠢记录,因为我没有回答正确的问题

在正则表达式的末尾有
|()\/?$)/
,这将使正则表达式匹配以斜杠结尾的URL。把它拿出来,我的测试结果显示你是金黄色的。

永远记住对操作数进行分组! 我可以假设这一点很难发现,但这都是因为您使用了or运算符
|
。您没有正确分组操作数,因此文章中描述的结果是无效的

在提供的情况下使用
|()
将匹配运算符
|
左侧的完整正则表达式

要解决此问题,您需要在应该进行或运算的操作数周围加上括号


查看哪里出了问题的一个简单方法是运行以下代码段:

$reg1 = "/(^(((www\.))|(?!(www\.)))domain\.com\/paramsindex\/([a-z]+)\/([a-z]+)\/((([a-z0-9]+)(\-[a-z0-9]+){0,})(\/([a-z0-9]+)(\-[a-z0-9]+){0,}){0,})|()\/?$
$reg2 = "/(^(((www\.))|(?!(www\.)))domain\.com\/paramsassoc\/([a-z]+)\/([a-z]+)\/((([a-z0-9]+)(\-[a-z0-9]+){0,})(\/([a-z0-9]+)(\-[a-z0-9]+){0,}){0,})|()\/?$
$uri  = "www.domain.com/paramsindex/cont/meth/par1/par2/par3/";

var_dump (preg_match($reg1, $uri, $match1));
var_dump (preg_match($reg2, $uri, $match2));

print_r ($match1);
print_r ($match2);
输出

int(1)
int(1)
Array
(
    [0] => www.domain.com/paramsindex/cont/meth/par1/par2/par3
    [1] => www.domain.com/paramsindex/cont/meth/par1/par2/par3
    [2] => www.
    [3] => www.
    [4] => www.
    [5] => 
    [6] => cont
    [7] => meth
    [8] => par1/par2/par3
    [9] => par1
    [10] => par1
    [11] => 
    [12] => /par3
    [13] => par3
)
Array
(
    [0] => /
    [1] => /
    [2] => 
    [3] => 
    [4] => 
    [5] => 
    [6] => 
    [7] => 
    [8] => 
    [9] => 
    [10] => 
    [11] => 
    [12] => 
    [13] => 
    [14] => 
    [15] => 
)
如您所见,
$reg2
匹配了
$uri
中的一组空字符串,这表明了我前面描述的内容


如果你对你要做的事情有一个简短的描述,我可以为你提供一个全功能(可能比你现在的正则表达式更简洁)的正则表达式。

永远记得对你的操作数进行分组! 我可以假设这一点很难发现,但这都是因为您使用了or运算符
|
。您没有正确分组操作数,因此文章中描述的结果是无效的

在提供的情况下使用
|()
将匹配运算符
|
左侧的完整正则表达式

要解决此问题,您需要在应该进行或运算的操作数周围加上括号


查看哪里出了问题的一个简单方法是运行以下代码段:

$reg1 = "/(^(((www\.))|(?!(www\.)))domain\.com\/paramsindex\/([a-z]+)\/([a-z]+)\/((([a-z0-9]+)(\-[a-z0-9]+){0,})(\/([a-z0-9]+)(\-[a-z0-9]+){0,}){0,})|()\/?$
$reg2 = "/(^(((www\.))|(?!(www\.)))domain\.com\/paramsassoc\/([a-z]+)\/([a-z]+)\/((([a-z0-9]+)(\-[a-z0-9]+){0,})(\/([a-z0-9]+)(\-[a-z0-9]+){0,}){0,})|()\/?$
$uri  = "www.domain.com/paramsindex/cont/meth/par1/par2/par3/";

var_dump (preg_match($reg1, $uri, $match1));
var_dump (preg_match($reg2, $uri, $match2));

print_r ($match1);
print_r ($match2);
输出

int(1)
int(1)
Array
(
    [0] => www.domain.com/paramsindex/cont/meth/par1/par2/par3
    [1] => www.domain.com/paramsindex/cont/meth/par1/par2/par3
    [2] => www.
    [3] => www.
    [4] => www.
    [5] => 
    [6] => cont
    [7] => meth
    [8] => par1/par2/par3
    [9] => par1
    [10] => par1
    [11] => 
    [12] => /par3
    [13] => par3
)
Array
(
    [0] => /
    [1] => /
    [2] => 
    [3] => 
    [4] => 
    [5] => 
    [6] => 
    [7] => 
    [8] => 
    [9] => 
    [10] => 
    [11] => 
    [12] => 
    [13] => 
    [14] => 
    [15] => 
)
如您所见,
$reg2
匹配了
$uri
中的一组空字符串,这表明了我前面描述的内容



如果你对你要做的事情有一个简短的描述,我可以为你提供一个功能齐全的正则表达式(可能比你现在的正则表达式要简洁一些)。

你的正则表达式乱七八糟,如果你想让它工作的话,你必须修改它

查看您的
参数索引的Rubular:

现在,对于
paramsassoc

它们都返回一个结果。当然,它是一个充满空字符串的数组,但它是一个非空的结果


这就是为什么两者都是正确的。

你的正则表达式乱七八糟,如果你想让它工作的话,你必须改变它

查看您的
参数索引的Rubular:

现在,对于
paramsassoc

它们都返回一个结果。当然,它是一个充满空字符串的数组,但它是一个非空的结果


这就是为什么这两个都是真的。

谢谢,我知道,但这两个不匹配,它们有明显的区别。然而,preg_match为他们两人都返回了1分:我想出了一些办法。。。如果我用这个正则表达式:^((www\)(?!(www\))domain\.com\/paramsindex\/([a-z]+)\/([a-z]+)\/([a-z0-9]+)(\-[a-z0-9]+){0,}(\/([a-z0-9]+)(\-[a-z0-9]+){0,})/?$很难看出这个长而糟糕的正则表达式中的区别,但我现在已经把它从匹配中去掉了,可以看到差异了!现在我需要找到其他方法来设置最后一个原子为可选的。。。但这仍然很奇怪,Rubular和RegExr都显示了相同的结果,只有PHP是“错误的”。是的,我刚刚注意到,我会立即更新我的答案来解释。谢谢,我知道,但这两个不匹配,它们有明显的区别。然而,preg_match为他们两人都返回了1分:我想出了一些办法。。。如果我用这个正则表达式:^((www\)(?!(www\))domain\.com\/paramsindex\/([a-z]+)\/([a-z]+)\/([a-z0-9]+)(\-[a-z0-9]+){0,}(\/([a-z0-9]+)(\-[a-z0-9]+){0,})/?$很难看出这个长而糟糕的正则表达式中的区别,但我现在已经把它从匹配中去掉了,可以看到差异了!现在我需要找到其他方法来设置最后一个原子为可选的。。。但还是很奇怪,,