2

可変長のものと一致させるためにpreg_match_all()を使用する正規表現に問題があります。

私が一致させようとしているのは、「混雑」という単語の後の交通状況です。私が思いついたのは、この正規表現パターンです。

Congestion\s*:\s*(?P<congestion>.*)

ただし、。*はすべてに一致するため、最初のインスタンスをサブジェクト全体の最後まで抽出します。しかし、それは私が望んでいることではありません。3つのインスタンスとして別々に一致させたいと思います。

混雑の背後にある単語は可変長である可能性があるため、より厳密な\ w * \ s * \ w *一致などを考え出すために、間にいくつの単語とスペースがあるかを実際に予測することはできません。

ここからどのように進めることができるかについての手がかりはありますか?

Highway : Highway 26
Datetime : 18-Oct-2010 05:18 PM
Congestion : Traffic is slow from Smith St to Alice Springs St

Highway : Princes Highway
Datetime : 18-Oct-2010 05:18 PM
Congestion : Traffic is slow at the Flinders St / Elizabeth St intersection

Highway : Eastern Freeway
Datetime : 18-Oct-2010 05:19 PM
Congestion : Traffic is slow from Prince St to Queen St

明確にするために編集

ここにあるこれらの非常に適切にフォーマットされたテキストは、実際には非常に不適切にフォーマットされたhtml電子メールを介して受信されます。そこにはランダムな改行が所々に含まれています。たとえば、「渋滞:Prince\nStからQueenStへの交通は\n遅い」などです。

そのため、メールの処理中に、すべてのhtmlコードとランダムな改行を取り除き、json_encode()を使用して、改行のない1つの非常に長い1行の文字列にしました...

4

3 に答える 3

4

通常、正規表現のマッチングは行ベースです。正規表現は、文字列が1行であると想定しています。「<code>m」(PCRE_MULTILINE)フラグを使用して、その動作を変更できます。次に、行の終わりにのみ一致するようにPHPに指示できます。

preg_match('/^Congestion\s*:\s*(?P<congestion>.*)$/m', $subject, $matches);

注意すべき点が2つあります。1つは、line-begin( )マーカー^とline-end($)マーカーを含むようにパターンが変更されたことです。次に、パターンにm修飾子が含まれるようになりました。

于 2010-10-18T10:14:20.730 に答える
2
Congestion\s*:\s*Traffic is\s*(?P<c1>[^\n]*)\s*from\s*(?P<c2>[^\n]*)\s*to\s*(?P<c3>[^\n]*)$
于 2010-10-18T10:13:45.720 に答える
2

最小限の一致を試すことができます:

Congestion\s*:\s*(?P<congestion>.*?)

これにより、輻輳文字列の直後に一致するものがない限り、名前付きグループ'congestion'でゼロ文字が返されます。

したがって、「高速道路」が常に交通状況の記録を開始する場合、これは修正される可能性があります。

Congestion\s*:\s*(?P<congestion>.*?)Highway\s*:

これが機能する場合(私はチェックしていません)、最初のレコードは一致しますが、最後のレコードは一致しません!これは、入力文字列の最後に「Highway:」というテキストを追加することで簡単に修正できます。

于 2010-10-18T11:24:06.837 に答える