Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/265.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 正则表达式中的分组_Php_Regex - Fatal编程技术网

Php 正则表达式中的分组

Php 正则表达式中的分组,php,regex,Php,Regex,我想进一步探讨正则表达式 这个正则表达式的结果 preg_replace("/(?=(.{3})*(.{4})$)/", "-", "1231231234"); is:123-123-1234 现在,我正在试验量词和组,但我不能使它们正常工作 为什么会这样(php) 这是: preg_replace("/(?=(.{3})*(.{4}){2}$)/", "-", "1212312312345678"); 两者都给了我一个大的8字符组作为输出 12-123-123-12345678 我可能期

我想进一步探讨正则表达式

这个正则表达式的结果

preg_replace("/(?=(.{3})*(.{4})$)/", "-", "1231231234");
is:123-123-1234

现在,我正在试验量词和组,但我不能使它们正常工作

为什么会这样(php)

这是:

preg_replace("/(?=(.{3})*(.{4}){2}$)/", "-", "1212312312345678");
两者都给了我一个大的8字符组作为输出

12-123-123-12345678
我可能期望第二个案例{2}的结果,但第一个案例没有

我预期的结果是:

12-123-123-1234-5678
1) ({4})({4})=({8})上的逻辑是什么,而不是两个不同的事件

2) 正确的分组是什么?

请注意,您在本例中使用的是。与正常匹配不同,它们实际上并不消耗匹配的东西

因此,在第一个示例中,有两个零宽度匹配,第一个零宽度匹配位于第一个
123
之后,因此前瞻匹配
1231234
,第二个零宽度匹配位于第二个
123
之后,其中前瞻匹配
1234
。您可能希望使用一个在线正则表达式测试程序来查看实际匹配的内容,我的选择是

因此,对于您的示例,您必须使前瞻也匹配最后4位数字(并且只匹配它们),实现这一点的一种方法是
(?=(({3})*({4}))?({4})$)
,使第一部分成为可选部分

请参见此处。

注意,您在本例中使用的是。与正常匹配不同,它们实际上并不消耗匹配的东西

因此,在第一个示例中,有两个零宽度匹配,第一个零宽度匹配位于第一个
123
之后,因此前瞻匹配
1231234
,第二个零宽度匹配位于第二个
123
之后,其中前瞻匹配
1234
。您可能希望使用一个在线正则表达式测试程序来查看实际匹配的内容,我的选择是

因此,对于您的示例,您必须使前瞻也匹配最后4位数字(并且只匹配它们),实现这一点的一种方法是
(?=(({3})*({4}))?({4})$)
,使第一部分成为可选部分

请参见此处。

(?=(.{3})*(.{4}{2}$)
匹配每个3xN字符序列,末尾2x4=8个字符,其中N>=0

要匹配从结尾开始的每个4xN字符,其中1
(?=(.{3})*(.{4}){2}$)
匹配每个3xN字符序列,结尾2x4=8个字符,其中N>=0


要匹配结尾处的每个4xN字符,其中1您似乎误解了正则表达式的工作原理。让我为您详细介绍一下:

(?=          lookahead assertion: the following pattern must match, but
             will not consume any of the text.
   (.{3})*   matches a series of 3 characters, any number of times. In
             other words, this consumes characters in multiples of 3.
   (.{4})$   makes sure there are exactly 4 characters left.
)
此模式在要插入破折号的每个位置生成空匹配。这就是为什么
preg_replace(“/(?=(.{3})*(.{4})$)/”、“-”、“1234”)在正确的位置插入破折号-替换空字符串与插入相同。让我们以文本
3123234
为例,一步一步地看一下:

         remaining text     remaining pattern      what happens
step 0:  31231234           (.{3})*(.{4})$         (.{3})* matches one time
step 1:  31234              (.{3})*(.{4})$         (.{3})* matches again
step 2:  34                 (.{3})*(.{4})$         (.{3})* fails to match another time
step 3:  34                 (.{4})$                (.{4}) fails to match -> backtrack
step 5:  31234              (.{4})$                (.{4}) fails to match -> pattern failed to
                                                   match, no dash will be inserted.
在文本中位置0处的模式匹配失败后,将在位置1处再次检查该模式(剩余文本为
1231234
):

同样的事情在3个字符后再次发生,给出最终结果
3-123-1234
。换句话说,组
(.{4})$
指定不应在文本的最后4个字符中插入破折号。通过使用最后4个字符,如果剩下的字符少于4个,则模式无法匹配。这就是为什么
(.{4})(.{4})$
(.{4}){2}$
都会产生一个8个字符的块-如果剩下的字符少于8个,则模式无法匹配

要在最后8个字符中插入另一个破折号,必须使用两组4个字符
{4}
,并将其中一个字符设置为可选:

(?=((.{3})*.{4})?(.{4})$)

你似乎误解了正则表达式的工作原理。让我为您详细介绍一下:

(?=          lookahead assertion: the following pattern must match, but
             will not consume any of the text.
   (.{3})*   matches a series of 3 characters, any number of times. In
             other words, this consumes characters in multiples of 3.
   (.{4})$   makes sure there are exactly 4 characters left.
)
此模式在要插入破折号的每个位置生成空匹配。这就是为什么
preg_replace(“/(?=(.{3})*(.{4})$)/”、“-”、“1234”)在正确的位置插入破折号-替换空字符串与插入相同。让我们以文本
3123234
为例,一步一步地看一下:

         remaining text     remaining pattern      what happens
step 0:  31231234           (.{3})*(.{4})$         (.{3})* matches one time
step 1:  31234              (.{3})*(.{4})$         (.{3})* matches again
step 2:  34                 (.{3})*(.{4})$         (.{3})* fails to match another time
step 3:  34                 (.{4})$                (.{4}) fails to match -> backtrack
step 5:  31234              (.{4})$                (.{4}) fails to match -> pattern failed to
                                                   match, no dash will be inserted.
在文本中位置0处的模式匹配失败后,将在位置1处再次检查该模式(剩余文本为
1231234
):

同样的事情在3个字符后再次发生,给出最终结果
3-123-1234
。换句话说,组
(.{4})$
指定不应在文本的最后4个字符中插入破折号。通过使用最后4个字符,如果剩下的字符少于4个,则模式无法匹配。这就是为什么
(.{4})(.{4})$
(.{4}){2}$
都会产生一个8个字符的块-如果剩下的字符少于8个,则模式无法匹配

要在最后8个字符中插入另一个破折号,必须使用两组4个字符
{4}
,并将其中一个字符设置为可选:

(?=((.{3})*.{4})?(.{4})$)

谢谢,是的,我一直在玩regex101:o),是的,有一件事我需要进一步了解,就是一种模式也与其他模式匹配。谢谢,是的,我一直在玩regex101:o),是的,有一件事我需要进一步了解,一种模式也与其他模式匹配。我很感兴趣。目前我不认为我会使用竖条,但这是一个很好的例子,谢谢。目前我不认为我会使用竖条,但这是一个很好的例子,谢谢。谢谢你的详细解释。还有一个问题。当使用$时,它真的是从该点开始的回溯搜索,还是某种从左到右的重复?例如,在这个简单的测试中:它说匹配是在20个步骤后找到的。@Rafael:
$
只是一个字符串结束锚,它不影响正则表达式的“方向”。如果你点击regex101上的“调试器”,你可以一步一步地看到它是如何匹配的。谢谢你的详细解释。还有一个问题。当我们