2017-05-11 24 views
0

preg_match()関数は、一致配列で見つからなかったグループを含むことができますか? ([0-9] +)???PHP:preg_matchに不一致のグループが含まれていますか?

/^([0-9] +)\ sの([^ IIBB])(:ここ

は、私が使用しているパターンです[iI])?([bB])?$/

私がしようとしているのは、人間が読めるサイズをバイト単位で解析することです。このパターンは私の要求に合っていますが、絶対グループ順で一致を検索できる場合に限ります。

これは最大5つのマッチグループを生成する可能性があり、インデックス0-5のマッチ配列になります。しかし、文字列がすべてのグループに一致しない場合、matches配列は実際にはグループ5をインデックス3に持つことがあります。

このパターン(5)の最終一致はいつもmatches配列の同じインデックスです。複数のグループはオプションであるため、マッチ配列を読み込むときに、マッチした式のグループを知ることが非常に重要です。

例状況:正規表現テスターregexr.comには、常に正しい順序で一致しないものを含む5つのグループがすべて表示されます。 「グローバル」と「マルチライン」のフラグを有効にして、次のテキストを使用すると、青いマッチの上にマウスを置くと、良いビジュアルが表示されます。

すべてのグループが常に一致するわけではありませんが、グループインデックスは常に正しい順序で表示されます。


編集:はい、私はすでに次のようにPHPでこれを試しました:

$matches = []; 
$matchesC = 0; 
$matchesN = 6; 
if (!preg_match("/^([0-9]+)(\.[0-9]+)?\s?([^iIbB])?([iI])?([bB])?$/", $size, $matches) || ($matchesC = count($matches)) < $matchesN) { 
    print_r($matches); 
    throw new \Exception(sprintf("Could not parse size string. (%d/%d)", $matchesC, $matchesN)); 
} 

$sizeは "256M" のときprint_r($matches);を返すこと:

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

グループ4と5が欠落しています。

+0

PHPでテストしましたか? https://ideone.com/NSm7Iyを参照してください。すべての「空の」グループがあります。 –

+0

はい。 matches配列のprint_r()には一致しないグループは含まれていないため、一致するグループのインデックスがスキューします。 – Adambean

+0

ええ、最後の項目は表示されませんが、そこにはあります(https://ideone.com/3ondVH)。あなたが必要とするのは、グループが空であるかどうか、 'empty($ m [n])'でチェックすることだけです。あるいは、 'print_r'が空のグループ値を*印刷するべきであるということは必須ですか? –

答えて

1

PHPでは空でない文字列値で初期化されていないので、グループ4とグループ5はnullの場合は'256M'文字列です。 preg_matchは、初期化されていない値を配列の末尾から破棄したようです。

あなたの場合、キャプチャグループはオプションではなく、オプションの中のパターンにすることができます。

$arr = array('500.2 KiB', '256M', '700 Mb', '1.2GiB'); 
foreach ($arr as $s) { 
    if (preg_match('~^([0-9]+)(\.[0-9]+)?\s?([^ib]?)(i?)(b?)$~i', $s, $m)) { 
     print_r($m) . "\n"; 
    } 
} 

出力:

Array 
(
    [0] => 500.2 KiB 
    [1] => 500 
    [2] => .2 
    [3] => K 
    [4] => i 
    [5] => B 
) 
Array 
(
    [0] => 256M 
    [1] => 256 
    [2] => 
    [3] => M 
    [4] => 
    [5] => 
) 
Array 
(
    [0] => 700 Mb 
    [1] => 700 
    [2] => 
    [3] => M 
    [4] => 
    [5] => b 
) 
Array 
(
    [0] => 1.2GiB 
    [1] => 1 
    [2] => .2 
    [3] => G 
    [4] => i 
    [5] => B 
) 

PHP demoを参照してください。

+0

私は既に、ヌル値を持つキーの 'var_dump()'ですでにチェックしていたと確信していました。グループを非オプションにすることは有効ですが、 '?'をグループに移動することはできません。代わりに私はこのパターンを使いました: '/^([0-9]+)\.?([0-9]*)\s?([^iIbB]*)([iI]*)([bB]*) $/' - サイドノート:" m "と" M "はIEC力率の意味が異なるため、この大文字と小文字が区別されます。 – Adambean

+0

ええ、私が言ったように、パターンをオプションにしました。 '*'はまた、アトムの0回の出現を一致させる量指定子です。正規表現**は**大文字と小文字を区別しません - ** '〜i' **を参照してください。また、 '\。?([0-9] *)'の代わりに '(?:\。?([0-9] +))?'を使うこともできると思います。 –

+0

各グループ内の '?'演算子が機能しなかったのは間違いです。 (私はそれを期待した。) – Adambean

関連する問題