0

数値に一致する正規表現を含む小さなコード スニペットがあり、その後にオプションのテキストが角かっこで囲まれ、文字「A」で終わります。例は

preg_match_all("/([0-9]+)(?:\[(.*)\])?A/", "123[SomeText]A345[SomeOtherText]A678A", $matches);
print_r($matches);

期待される結果は、3 つの一致があることです。

Array
(
    [0] => Array
        (
            [0] => 123[SomeText]A
            [1] => 345[SomeOtherText]A
            [2] => 678A
        )

    [1] => Array
        (
            [0] => 123
            [1] => 345
            [2] => 678
        )

    [2] => Array
        (
            [0] => SomeText
            [1] => SomeOtherText
            [2] => 
        )
)

上記のコードは 2 回しか一致しませんが、

Array
(
    [0] => Array
        (
            [0] => 123[SomeText]A345[SomeOtherText]A
            [1] => 678A
        )

    [1] => Array
        (
            [0] => 123
            [1] => 678
        )

    [2] => Array
        (
            [0] => SomeText]A345[SomeOtherText
            [1] => 
        )
)

指定された正規表現で何が間違っているのかわかりません。正規表現を修正するための提案は大歓迎です。

4

4 に答える 4

3

あなたの問題は貪欲です。量指定子 ( など.*) は可能な限り消費します。また、.一致]する可能性があるため、最初の締め切りを過ぎ]て最後の締め切りまで進みます。.*?. _ しかし、あなたの場合、より良い(より速い)オプションがあります。]許可された文字からそれを削除して、終了を通過できないことを確認してください。

/([0-9]+)(?:\[([^\]]*)\])?A/

動作デモ。

閉じ括弧はクラスの最初の文字であるため (また、空のクラスは許可されていないため、エスケープする必要はありません)、実際にはエスケープする必要はありません。もう 1 つはクラスの外にあります。 、したがって、閉じ括弧にすることもできません:

/([0-9]+)(?:\[([^]]*)])?A/

動作デモ。

どちらのバリエーションを好むかは、好みの問題だと思います。

于 2013-08-12T11:28:35.983 に答える
2

.* は貪欲なので、次のように変更します。

<?php
preg_match_all("/([0-9]+)(?:\[([^A]*)\])?A/", "123[SomeText]A345[SomeOtherText]A678A", $matches);
print_r($matches);

試してみてください: http://3v4l.org/BZgmH

于 2013-08-12T11:28:21.793 に答える
0

このパターンはどうですか?

\d+(\[.*?\])?A
于 2013-08-12T11:28:15.233 に答える
0

テキストに「A」文字が含まれていないことが確実な場合は、次のようにします。

'/(\d*)([^A]*)/'

ただし、各部分が最初に数字を持つ新しい部分で終わる場合、これは機能するはずです:

'/(\d*)([^\d]*)/'

この行で

preg_match_all('/(\d*)([^\d]*)/', "123[SomeText]A345[SomeOtherText]A678A", $matches, PREG_SET_ORDER);
print_r($matches);
于 2013-08-12T11:50:05.957 に答える