1

私は文字列を持っています:

$day = "11.08.2012 PROC BRE-AMS 08:00-12:00 ( MIETWAGEN MIT BAK RES 6049687886 ) Y AMS-AMS 13:15-19:15"

そして、私は正規表現を持っています:

$data = preg_split("/(?=[A-Z]{1,4}[\s]+[A-Z]{3}[\-][A-Z]{3}[\s]+)/", $day);

予想される$data-Array は次のようになります。

array
      0 => string '11.08.2012 ' (length=11)
      1 => string 'PROC 08:00-12:00 ( MIETWAGEN MIT BAK RES 6049687886 ) ' (length=22)
      2 => string 'Y AMS-AMS 13:15-19:15' (length=21)

しかし、私の結果は次のとおりです。

0 => string '11.08.2012 ' (length=11)
      1 => string 'P' (length=1)
      2 => string 'R' (length=1)
      3 => string 'O' (length=1)
      4 => string 'C BRE-AMS 08:00-12:00 ( MIETWAGEN MIT BAK RES 6049687886 ) ' (length=59)
      5 => string 'Y AMS-AMS 13:15-19:15' (length=21)

ここで何が起こっているのかを遡ることはできません。誰か説明してくれませんか?

4

2 に答える 2

3

要するに、問題は、パターン内の (?=...) 部分式がposition に一致することです。それがまさにあなたの意図であることを理解しています。問題は、(?=) で指定されたパターンが一致を終了したときではなく、先読み + 1 シンボルに一致した位置で次の一致が開始されることです。

このプロセスを詳しく確認しましょう。最初に分割が試行されると、アスタリスクでマークされた位置に到達するまで文字列を移動します。

11.08.2012 *PROC BRE-AMS 08:00-12:00

...指定されたパターンに一致する場所。次の試行では、開始位置が 1 つのシンボルに「ぶつかる」ので、次のようになります。

11.08.2012 P*ROC BRE-AMS 08:00-12:00

...そしてほら、その量指定子のおかげで、このパターンに再び{1,4}一致させることができます! Pそれが、これらの「不規則な」RおよびO記号を取得した方法です。


これは説明用です。今度は「修正方法」の部分です。これを回避する最も簡単な方法は、分割パターンに次の小さなひねりを加えることだと思います。

$data = preg_split('/\b(?=[A-Z]{1,4}\s+[A-Z]{3}-[A-Z]{3}\s+)/', $day);

引き続き位置を照合しますが、この位置は「単語」記号を単語以外の記号から分離する位置である必要があります。同じ考え方は、否定的な後読みパターンで表現できます。

$data = preg_split('/(?<![A-Z])(?=[A-Z]{1,4}\s+[A-Z]{3}-[A-Z]{3}\s+)/', $day);

...実際にはより正確ですが、エレガントではないと思います。)

ここで 2 つの注意点があります。1) 単一のシンボル (単純な-- または「ショートカット」のようなもの\s) を指定する必要がある場合は、文字クラスの構文を使用しないでください。2) 一部の変数を補間したい場合を除き、単一引用符を使用してパターンを区切ります。

于 2012-12-12T12:40:29.080 に答える
2

ハイフンは文字クラスのメタ文字です。文字クラスにハイフンを含めたい場合は、バックスラッシュでエスケープする必要があります (ただし、この特定のケースでは、文字クラスにはハイフンしかないため機能します)。

分割文字列を含める必要がある場合は、先読みの開始を単語境界に固定して、最初の 1 ~ 4 文字シーケンスの最初の文字のみがテストされるようにします。

/(?=\b[A-Z]{1,4}\s+[A-Z]{3}-[A-Z]{3}\s+)/'
于 2012-12-12T12:35:26.383 に答える