Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/249.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.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_Preg Match_Numeric_Capture Group - Fatal编程技术网

Php 如何搜索相邻的重复号码?

Php 如何搜索相邻的重复号码?,php,regex,preg-match,numeric,capture-group,Php,Regex,Preg Match,Numeric,Capture Group,我试图在PHP中使用preg_match()为具有此模式的4位数字进行模式匹配: 0033 1155 2277 基本上,前两位数字相同,后两位数字相同,但并非所有4位数字都相同 preg\u match()是正确的函数吗?或者我应该将它们拆分并以这种方式匹配吗?您可以使用类似于比较回调的方法: function compare($number) { // Compare first 2 numbers if (intval($number[0]) !== intval($num

我试图在PHP中使用
preg_match()
为具有此模式的4位数字进行模式匹配:

0033
1155
2277
基本上,前两位数字相同,后两位数字相同,但并非所有4位数字都相同


preg\u match()
是正确的函数吗?或者我应该将它们拆分并以这种方式匹配吗?

您可以使用类似于比较回调的方法:

function compare($number) {
    // Compare first 2 numbers
    if (intval($number[0]) !== intval($number[1])) {
        return false;
    }

    // Compare last 2 numbers
    if (intval($number[2]) !== intval($number[3])) {
        return false;
    }

    // Make sure first and last numbers aren't the same
    if (intval($number[0]) === intval($number[3])) {
        return false;
    }

    return true;
}

$data = array_filter($data, 'compare');
您也可以使用闭包执行此操作:

$data = array_filter($data, function($number) {
    return intval($number[0]) === intval($number[1]) && intval($number[2]) === intval($number[3]) && intval($number[0]) !== intval($number[3]);
});

这里的示例:

您可以将类似的内容与比较回调一起使用:

function compare($number) {
    // Compare first 2 numbers
    if (intval($number[0]) !== intval($number[1])) {
        return false;
    }

    // Compare last 2 numbers
    if (intval($number[2]) !== intval($number[3])) {
        return false;
    }

    // Make sure first and last numbers aren't the same
    if (intval($number[0]) === intval($number[3])) {
        return false;
    }

    return true;
}

$data = array_filter($data, 'compare');
您也可以使用闭包执行此操作:

$data = array_filter($data, function($number) {
    return intval($number[0]) === intval($number[1]) && intval($number[2]) === intval($number[3]) && intval($number[0]) !== intval($number[3]);
});

此处示例:

要在文本中搜索此类数字,可以使用:

preg_match('~\b(\d)\1(?!\1)(\d)\2\b~', $str, $m)
(或使用
preg\u match\u all
,如果您想要全部匹配)

详情:

~        # pattern delimiter
\b       # word boundary (to be sure that 1122 isn't a part of 901122)
(\d)     # capture the first digit in group 1
\1       # back-reference to the group 1
(?!\1)   # negative lookahead: check if the reference doesn't follow
(\d)     #
\2       #
\b       # word boundary (to be sure that 1122 isn't a part of 112234)
~        #
如果要检查整个字符串是否为数字,请使用字符串限制定位代替单词边界:

~\A(\d)\1(?!\1)(\d)\2\z~

要在文本中搜索此类数字,可以使用:

preg_match('~\b(\d)\1(?!\1)(\d)\2\b~', $str, $m)
(或使用
preg\u match\u all
,如果您想要全部匹配)

详情:

~        # pattern delimiter
\b       # word boundary (to be sure that 1122 isn't a part of 901122)
(\d)     # capture the first digit in group 1
\1       # back-reference to the group 1
(?!\1)   # negative lookahead: check if the reference doesn't follow
(\d)     #
\2       #
\b       # word boundary (to be sure that 1122 isn't a part of 112234)
~        #
如果要检查整个字符串是否为数字,请使用字符串限制定位代替单词边界:

~\A(\d)\1(?!\1)(\d)\2\z~


作为记录,尝试为此使用正则表达式是相当困难的。这可能是可以做到的,但我无法想象结果会是什么样子。需要两组重复数字不同,这使得编写正则表达式非常困难。你最好使用其他解决方案。如果您可以免除该要求,
(\d)\1(\d)\2
可能会起作用。@Joel我能问一下\1和\2是什么意思吗?因为如果我有一个编号113022,它将匹配到(\d)\1[30]+(\d)\2。为什么?我以为\1和\2是数字的位置…这些是捕获组引用。这允许您指定捕获组应加倍或加倍,或者您想要的任何内容。通过添加边界
^(\d)\1(\d)\2$
,可以防止它接受该排序的输入。这将把你的输入限制为4位数的“单词”。@Joel这实际上适用于我想做的其他事情。我想用像so XXYY2XX这样的模式匹配电话号码。x和y可以是与另一个x匹配的任何数字。因此4455233将与上述模式相匹配。谢谢你!作为记录,尝试为此使用正则表达式是相当困难的。这可能是可以做到的,但我无法想象结果会是什么样子。需要两组重复数字不同,这使得编写正则表达式非常困难。你最好使用其他解决方案。如果您可以免除该要求,
(\d)\1(\d)\2
可能会起作用。@Joel我能问一下\1和\2是什么意思吗?因为如果我有一个编号113022,它将匹配到(\d)\1[30]+(\d)\2。为什么?我以为\1和\2是数字的位置…这些是捕获组引用。这允许您指定捕获组应加倍或加倍,或者您想要的任何内容。通过添加边界
^(\d)\1(\d)\2$
,可以防止它接受该排序的输入。这将把你的输入限制为4位数的“单词”。@Joel这实际上适用于我想做的其他事情。我想用像so XXYY2XX这样的模式匹配电话号码。x和y可以是与另一个x匹配的任何数字。因此4455233将与上述模式相匹配。谢谢你!好的,看起来是这样。不知道我是否需要创建一个新的问题,但是将您的代码带到那里,有没有一种方法可以自动使用它来匹配这样的任何模式?XXYY0所以XX表示相同的数字,YY表示相同的数字,但与XX不同,然后是0,只是搜索0。或者图案可以是XXX0,这样5550就会匹配。你能想出一种方法来编写代码,动态地构建匹配的代码以匹配所传递的任何模式吗?不管是哪种方法,我都会接受你的答案,只是想看看我们是否可以再使用一步来匹配我上面提到的模式。@John你可以使用这个:好的,看起来像这样。不知道我是否需要创建一个新的问题,但是将您的代码带到那里,有没有一种方法可以自动使用它来匹配这样的任何模式?XXYY0所以XX表示相同的数字,YY表示相同的数字,但与XX不同,然后是0,只是搜索0。或者图案可以是XXX0,这样5550就会匹配。你能想出一种方法来编写代码,动态构建匹配代码,以匹配所传递的任何模式吗?不管是哪种方法,我都会接受你的答案,只是想看看我们是否可以再使用一步来匹配我上面提到的模式。@John你可以使用这个方法:这个答案不要求每个字符都是数字,而
str_split()
是不必要的,因为可以使用字符串偏移量进行相同的比较。使用三个单独的if语句意味着代码膨胀,最好使用一组条件,如匿名
array\u filter()
方法。Casimir的模式/方法可以根据需要执行,并且可以与其他正则表达式模式结合使用,以便在一个步骤中提取更多数据。@mickmackusa您不需要使用
str_split
是正确的,但是,即使它是更多的代码,但它在一次运行中比使用
preg_match
更有效,这将在一段时间内加剧较大的数据集:/。我在方法中分解了它,以便OP可以看到每个语句都在做什么。您可以通过在处理之前强制转换为int或使用sprintf来绕过字符串限制,因为这将导致字符串在第三个条件下失败,因为每个字母都将强制转换为零。现在看起来,每次迭代都有3次比较和6次函数调用。我更喜欢一个
preg_match()
调用。我们会同意不同意,即使调用次数是原来的6倍,效率也会提高大约5倍。在没有正则表达式的情况下这样做不是个坏主意。您可以在上次测试中改进
compare
函数删除
intval
,但您可以