正規表現を使用して一部のデータを「解析」しようとしてきましたが、近づいているように感じますが、すべてを家に持ち帰ることができないようです。
通常、解析が必要なデータは次のようになります<param>: <value>\n
。パラメータの数は、値と同様に変更できます。それでも、ここに例があります:
FooID: 123456 名前:チャック 日時: 2013 年 1 月 2 日 01:23:45 内部 ID: 789654 ユーザーメッセージ: こんにちは。 これは nillable ですが、非常に長くなる可能性があります。テキストは複数の行にまたがることができます また、任意の数の \n で開始できます。空にすることもできます。 さらに悪いことに、これにはコロンを含めることができます (ただし、`\` を使用して_"エスケープ"_されます)、さらには基本的なマークアップです!
このテキストをオブジェクトにプッシュするために、この小さな表現をまとめました
if (preg_match_all('/^([^:\n\\]+):\s*(.+)/m', $this->structuredMessage, $data))
{
$data = array_combine($data[1], $data[2]);
//$data is assoc array FooID => 123456, Name => Chuck, ...
$report = new Report($data);
}
User Message
さて、これはビットを除いてほとんどの場合問題なく動作します:.
新しい行に一致しません。s
フラグを使用すると、2 番目のグループはFooID:
文字列の最後まですべてに一致するためです。
そのためには、汚い回避策を使用する必要があります。
$msg = explode(end($data[1], $string);
$data[2][count($data[2])-1] = array_pop($msg);
いくつかのテストの後、1 つまたは 2 つのパラメーターが入力されていない場合があることがわかりました (たとえば、InternalID
が空である可能性があります)。その場合、私の式は失敗しませんが、結果は次のようになります。
[1] => 配列 ( [0] => FooID [1] => 名前 [2] =>いつ [3] => 内部 ID ) [2] => 配列 ( [0] => 123465 [1] => チャック [2] => 2013 年 1 月 2 日 01:23:45 [3] => ユーザーのコメント: こんにちは。 )
いろいろな表現を試した結果、以下のようになりました。
/^([^:\n\\]++)\s{0,}:(.*+)(?!^[^:\n\\]++\s{0,}:)/m
//or:
/^([^:\n\\]+)\s{0,}:(.*)(?!^[^:\\\n]+\s{0,}:)/m
2 番目のバージョンは少し遅くなります。
これで私が抱えていた問題は解決しましたInternalID: <void>
が、それでも最後の障害が残っていますUser Message: <multi-line>
。フラグを使用してs
も、私の表現 ATM ではうまくいきません。
私はこれしか考えられません:
^([^:\n\\]++)\s{0,}:((\n(?![^\n:\\]++\s{0,}:)|.)*+)
少なくとも私の目には、これは複雑すぎて唯一の選択肢にはなりません。アイデア、提案、リンク、...何でも大歓迎です