2

I am having a difficult time getting my regular expression code to work properly in PHP. Here is my code:

$array = array(); // Used to satisfy the 3rd argument requirment of preg_match_all.
$regex = '/(012|345|678|987|654|321|123|456|789|876|543|210|234|567|765|432)/';
$subject = '123456';
echo preg_match_all($regex, $subject, $array).'<br />';
print_r($array);

When this code is ran it will output:

2
Array
(
    [0] => Array
        (
            [0] => 123
            [1] => 456
        )
    [1] => Array
        (
            [0] => 123
            [1] => 456
        )
)

What can I do so that it will match 123, 234, 345 and 456?

Thanks in advance!

4

4 回答 4

2

正则表达式不是这项工作的正确工具(它不会返回“子匹配”)。只需strpos循环使用。

$subject = '123456';

$seqs = array('012', '345', '678', '987', '654', '321', '123', '456', '234');
foreach ($seqs as $seq) {
    if (strpos($subject, $seq) !== false) {
        // found
    }
}
于 2011-01-04T19:11:18.403 回答
1
$regex = '/(?=(012|345|678|987|654|321|123|456|789|876|543|210|234|567|765|432))/';
$subject = '123456';
preg_match_all($regex, $subject, $array);
print_r($array[1]);

输出:

Array
(
    [0] => 123
    [1] => 234
    [2] => 345
    [3] => 456
)

您正在尝试检索在主题字符串中相互重叠的匹配项,这通常是不可能的。但是,在许多情况下,您可以通过将整个正则表达式包装在捕获组中来伪造它,然后将其包装在前瞻中。因为前瞻在匹配时不消耗任何字符,所以正则表达式引擎在每次成功匹配后手动向前移动一个位置,以避免陷入无限循环。但是捕获组仍然有效,因此您可以按常规方式检索捕获的文本。

请注意,我只打印了第一个捕获组 ( $array[1]) 的内容。如果我打印了整个数组数组 ( $array),它会是这样的:

Array
(
    [0] => Array
    (
        [0] => 
        [1] => 
        [2] => 
        [3] => 
    )

    [1] => Array
    (
        [0] => 123
        [1] => 234
        [2] => 345
        [3] => 456
    )
)

在ideone上看到它

于 2011-01-05T03:56:33.633 回答
0

是的,这是一个 hack,但你可以使用 RegEx

<?php
$subject = '123456';

$rs = findmatches($subject);
echo '<pre>'.print_r($rs,true).'</pre><br />';


function findmatches($x) {
    $regex = '/(\d{3})/'; 

    // Loop through the subject string
    for($counter =  0; $counter <= strlen($x); $counter++) {
        $y = substr($x, $counter);
        if(preg_match_all($regex, $y, $array)) {
            $rs_array[$counter] = array_unique($array);
        }
    }

    // Parse results array
    foreach($rs_array as $tmp_arr) {
        $rs[] = $tmp_arr[0][0];
    }
    return $rs;
}
?>

回报:

Array
(
    [0] => 123
    [1] => 234
    [2] => 345
    [3] => 456
)

注意:这仅适用于并发号码

于 2011-01-04T22:25:38.147 回答
0

可以用正则表达式来完成。您的原始代码的问题是,一旦发生匹配,字符就会被消耗掉并且正则表达式不会回溯。这是一种方法:

$array = array(); // Used to satisfy the 3rd argument requirment of preg_match_all.
$regex = '/012|345|678|987|654|321|123|456|789|876|543|210|234|567|765|432/';
$subject = '123456';

$tempSubject = $subject;
$finalAnswer = array();
do {
    $matched = preg_match($regex, $tempSubject, $array);
    $finalAnswer = array_merge($finalAnswer, $array);
    $tempSubject = substr($tempSubject, 1);
} while ($matched && (strlen($tempSubject >= 3)));
print_r($finalAnswer);

但是,正如另一个答案中所建议的那样,正则表达式可能不是在这种情况下使用的正确工具,具体取决于您的更大目标。另外,上面的代码可能不是用正则表达式解决这个问题的最有效的方法(wrt memory 或 wrt performance)。这只是一个简单的满足要求的解决方案。

于 2011-01-04T19:22:59.027 回答