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上的“调试器”,你可以一步一步地看到它是如何匹配的。谢谢你的详细解释。还有一个问题。当我们