0

次の正規表現がなぜ:$regex = '/\b(V|E)?\d{1,2}? ?\d{3} ?\d{3}\b/i'; 以下のすべての入力と一致しないのか

(V|E)?\d{1,2}? ?これにより、文字、最初の1つまたは2つの数字、および最初のスペースがオプションになると思いました。

入力

<?php

$sms = array(
    'test test test 11 111 111 test test test',
    'test test test 1 111 111 test test test',
    'test test test 111 111 test test test', // does not match
    'test test test test test test 11111111',
    'test test test 1111111 test test test',
    'test test test 111111 test test test', // does not match
    'test test test E11 111 111 test test test',
    'test test test V1 111 111 test test test',
    'test test test V111 111 test test test', // does not match
    'test test test V11111111 test test test',
    'test test test V1111111 test test test',
    'test test test E111111 test test test', // does not match
    'test test test V 11 111 111 test test test',
    'test test test V 1 111 111 test test test',
    'test test test E 111 111 test test test', // does not match
    'test test test V 11111111 test test test',
    'test test test V 1111111 test test test',
    'test test test V 111111 test test test', //does not match
    'test test test V11 111 111 test test test',
    'test test test V1 111 111 test test test',
    'test test test E111 111 test test test', //does not match
    'test test test V11111111 test test test',
    'V1111111 test test test  test test test',
    'test test test V111111 test test test', // does not match
);

$regex = '/\b(V|E)?\d{1,2}? ?\d{3} ?\d{3}\b/i';
$noMatches = 0;
$index = 0;
foreach($sms as $v) {
    $match = preg_match($regex, $v, $matches);



    if($match) {
        //print_r($matches);
        //echo "$v match!\n";
        //$matches++;
    }
    else {
        echo "$index - $v does NOT match!\n";
        $noMatches++;
    }
    $index++;
}
$total = count($sms);
echo "\n\nTotal: $total\nNo Matches: $noMatches\n";

出力

$ php test-regex.php 
2 - test test test 111 111 test test test does NOT match!
5 - test test test 111111 test test test does NOT match!
8 - test test test V111 111 test test test does NOT match!
11 - test test test E111111 test test test does NOT match!
14 - test test test E 111 111 test test test does NOT match!
17 - test test test V 111111 test test test does NOT match!
20 - test test test E111 111 test test test does NOT match!
23 - test test test V111111 test test test does NOT match!


Total: 24
No Matches: 8

編集:

マリオの提案を使用すると、正規表現は現在$regex = '/\b(V|E)?\d{0,2} ?\d{3} ?\d{3}\b/i';、なぜこの正規表現は文字をキャプチャしないVか、E

$output = array(
    'test test test E11 111 111 test test test' => 'E11 111 111',
    'test test test V1 111 111 test test test' => 'V1 111 111',
    'test test test V111 111 test test test' => 'V111 111',
    'test test test V11111111 test test test' => 'V11111111',
    'test test test V1111111 test test test' => 'V1111111',
    'test test test E111111 test test test' => 'E111111',
    'test test test V 11 111 111 test test test' => '11 111 111', // Missing Letter
    'test test test V 1 111 111 test test test' => '1 111 111', // Missing Leter
    'test test test E 111 111 test test test' => 'E 111 111',
    'test test test V 11111111 test test test' => '11111111', // Missing Letter
    'test test test V 1111111 test test test' => '1111111', // Missing Letter
    'test test test V 111111 test test test' => 'V 111111',
    'test test test V11 111 111 test test test' => 'V11 111 111',
    'test test test V1 111 111 test test test' => 'V1 111 111',
    'test test test E111 111 test test test' => 'E111 111',
    'test test test V11111111 test test test' => 'V11111111',
    'V1111111 test test test  test test test' => 'V1111111',
    'test test test V111111 test test test' => 'V111111',
    'V 1111111 test test test' => '1111111', // Missing Letter
    'test test test V 1111111 test test test' => '1111111', // Missing Letter
);
4

3 に答える 3

2

?グループまたはリテラル文字または文字クラスの後の量指定子のみです。

If?が別の量指定子*or +andの後に発生{n,m}すると、マッチングが貪欲でなくなります。つまり、正規表現は最小量と一致しようとします。

だから\d{1,2}?任意というわけではありません。これは、1 つまたは 2 つの一致を意味しますが、1 つだけに一致することを好みます。\d{0,2}あなたは代わりに書くつもりでした。

于 2013-01-16T23:19:41.903 に答える
1

正規表現には合計で少なくとも 7 桁が必要なため、一致しません。

/\b(V|E)?\d{1,2}? ?\d{3} ?\d{3}\b/
             |        |      |
             |        |      \-------->  3 digits exactly
             |        \--------------->  3 digits exactly
             \------------------------>  1 or 2 digits (prefers 1, but will match
                                         2 if there are 8 digits in a row)

失敗した入力はすべて 1 桁不足しています。

于 2013-01-16T23:19:13.700 に答える
1

最初の部分を完全にオプションにしたい場合は、括弧で囲み、それに a?を追加する必要があります。文字グループを使用することもできますV|E

(?:[VE]\d{1,2} )?
于 2013-01-16T23:19:46.467 に答える