2

PHP で正規表現コードを正しく動作させるのに苦労しています。これが私のコードです:

$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);

このコードを実行すると、次のように出力されます。

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

123、234、345、456 と一致するようにするにはどうすればよいですか?

前もって感謝します!

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
)

件名の文字列で互いに重複する一致を取得しようとしていますが、これは通常不可能です。ただし、多くの場合、正規表現全体をキャプチャ グループでラップし、それを先読みでラップすることで偽装できます。先読みは一致時に文字を消費しないため、正規表現エンジンは、一致が成功するたびに手動で 1 つ前の位置に移動し、無限ループに陥らないようにします。ただし、キャプチャ グループは引き続き機能するため、通常の方法でキャプチャされたテキストを取得できます。

最初のキャプチャ グループ ( $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

ええ、それはハックですが、正規表現を使用できます

<?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

正規表現で実行できます。元のコードの問題は、一致が発生するとすぐに文字が消費され、正規表現がバックトラックしないことです。これを行う1つの方法は次のとおりです。

$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);

ただし、別の回答で示唆されているように、より大きな目標によっては、正規表現はこの状況で使用する正しいツールではない場合があります。さらに、上記のコードは、これを正規表現で解決するための最も効率的な方法 (メモリまたはパフォーマンス) ではない可能性があります。これは、要件を満たす単純なソリューションです。

于 2011-01-04T19:22:59.027 に答える