0

PHPのpreg_match_allを使用して、これらのそれぞれを独自のグループにキャプチャしたいと思います。

  1. 章、セクション、またはページ
  2. 指定された章、セクション、またはページの番号(または文字がある場合は文字)。それらの間に単一のスペースがある場合は、それを考慮に入れる必要があります
  3. 「and」、「or」という言葉

すべての本のタイトルを無視したいので、文字列内のアイテムの数は動的である可能性があることを念頭に置いて、正規表現は以下のすべての例で機能するはずです。

  1. Ch1とSect2b
  2. Ch4x不要なタイトルとSect5y不要なタイトルとSect6zとCh7またはCh8

これは私がこれまでに思いついたものです:

    $str = 'Ch 1 a unwantedtitle and Sect 2b unwanted title and Pg3';
    preg_match_all ('/([a-z]+)(?=\d|\d\s)\s*(\d*)\s*(?<=\d|\d\s)([a-z]?).*?(and|or)?/i', $str, $matches);

    Array
    (
        [0] => Array
            (
                [0] => Pg3
            )

        [1] => Array
            (
                [0] => Pg
            )

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

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

        [4] => Array
            (
                [0] => 
            )

    )

期待される結果は次のようになります。

    Array
    (
        [0] => Array
            (
                [0] => Ch 1 a and 
                [1] => Sect 2b and 
                [2] => Pg3
            )

        [1] => Array
            (
                [0] => Ch
                [1] => Sect
                [2] => Pg
            )

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

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

        [4] => Array
            (
                [0] => and
                [1] => and
                [2] => 
            )

    )
4

2 に答える 2

0

これは私がそれを行う方法です。

$arr = array(
    'Ch1 and Sect2b',
    'Ch 1 a unwantedtitle and Sect 2b unwanted title and Pg3',
    'Ch 4 x unwantedtitle and Sect 5y unwanted title and' .
        ' Sect6 z and Ch7 or Ch8a',
    'Assume this is ch1a and ch 2 or ch seCt 5c.' .
        ' Then SECT or chA pg22a and pg 13 andor'
);

foreach ($arr as $a) {
    var_dump($a);
    preg_match_all(
    '~
        \b(?P<word>ch|sect|(pg))
        \s*(?P<number>\d+)
        (?(2)\b|
            \s*
            (?P<letter>(?!(?<=\s)(?:and|or)\b)[a-z]+)?
            \s*
            (?:(?<=\s)(?P<cond>and|or)\b)?
        )
    ~xi'
    ,$a,$m);
    foreach ($m as $k => $v) {
        if (is_numeric($k) && $k !== 0) unset($m[$k]);
        // this is for 'beautifying' the result array
        // note that $m[0] will still return whole matches
    }
    print_r($m);
}

そのための条件を明示的に記述する必要があったため、キャプチャ グループにpg変換する必要がありました。つまり、数値を追加することはできますが (スペースの有無にかかわらず)、ページ インジケーターを考慮して文字を追加することはできません。 「pg23a」のような文字を持っています。

そのため、各グループに名前を付け、コード内の内側の foreach ループによって結果を「美しく」することにしました。それ以外の場合、(名前付きインデックスではなく) 数値インデックスを使用する場合は、それぞれをスキップする必要があります$m[2]

例を示すために、 の最後の項目の出力を次に示します$arr

Array
(
    [0] => Array
        (
            [0] => ch1a and
            [1] => ch 2 or
            [2] => seCt 5c
            [3] => pg 13
        )

    [word] => Array
        (
            [0] => ch
            [1] => ch
            [2] => seCt
            [3] => pg
        )

    [number] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 5
            [3] => 13
        )

    [letter] => Array
        (
            [0] => a
            [1] => 
            [2] => c
            [3] => 
        )

    [cond] => Array
        (
            [0] => and
            [1] => or
            [2] => 
            [3] => 
        )

)
于 2013-01-14T00:07:26.203 に答える
0

これは私が得ることができる最も近いものです:

$str = 'Ch 1 a unwantedtitle and Sect 2b unwanted title and Pg3';
preg_match_all ('/((Ch|Sect|Pg)\s?(\d+)\s?(\w?))(.*?(and|or))?/i', $str, $matches);


Array
(
    [0] => Array
        (
            [0] => Ch 1 a unwantedtitle and
            [1] => Sect 2b unwanted title and
            [2] => Pg3
        )

    [1] => Array
        (
            [0] => Ch 1 a
            [1] => Sect 2b
            [2] => Pg3
        )

    [2] => Array
        (
            [0] => Ch
            [1] => Sect
            [2] => Pg
        )

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

    [4] => Array
        (
            [0] => a
            [1] => b
            [2] => 
        )

    [5] => Array
        (
            [0] =>  unwantedtitle and
            [1] =>  unwanted title and
            [2] => 
        )

    [6] => Array
        (
            [0] => and
            [1] => and
            [2] => 
        )

)
于 2013-01-13T19:23:57.400 に答える