0

次のような形式のアップロードされたテキストファイルを解析することになっているPHPアプリケーションがあります。

|                  |                |                  |
| -----------------------------------------------------|
| Sample           | Data           |                  |
| -----------------------------------------------------|
| Sample           | Data           |                  |
| -----------------------------------------------------|
| Sample           | Data           |                  |
| -----------------------------------------------------|


| Accepts                    |                            |
| --------------------------------------------------------|
| All                        | Yes                        |
| --------------------------------------------------------|
| More                       | Yes                        |
| --------------------------------------------------------|


|            |            | Years      |            |            |
| ---------------------------------------------------------------|
| 1998       | 1999       | 2000       | 2001       | 2002       |
| ---------------------------------------------------------------|
| 2003       | 2004       | 2005       | 2006       | 2007       |
| ---------------------------------------------------------------|
| 2008       | 2009       | 2010       | 2011       | 2012       |
| ---------------------------------------------------------------|

私がする必要があるのは、基本的に各「ブロック」を同じ順序で単独で分離することです。これにより、それらを1つずつループさせることができます。「解決策」は

preg_split("/\n{4,}/", $text);

ただし、テキストを送信する人が不要な改行が属していないことを決定し、それらを削除した場合、それは不当な結果を生み出します。preg_match_all()を試してみましたが、実際の正規表現を実行してから何年も経っていたため、使用可能な解決策を思い付くことができませんでした。

「ブロック」の最初の行には常に|が含まれます とスペースがありますが、フィールドにはテキストが含まれる場合があります。「ブロック」の最後の行は常にパイプの後にスペースが続き、行を埋めるためにダッシュが続き、|で終わります。

4

3 に答える 3

0

これがテキストファイルの内容がどのように見えるかであるならば、私は次のようなものを書くでしょう

$pat = '~
    (?<=^|\r{3}|\n{3}|(\r\n){3})    # beginning of string or following 3 newline chars
        \|[ ]                       # a pipe and a space
        (
            [ \S]+                      # 1 or more space or non space char
            \|                          # a pipe
        )+                          # 1 or more of this group

        (\n|\r\n?)                  # a newline
        \|[ ]-+\|                   # a pipe, a space, multiple dashes and a pipe
        (\n|\r\n?)                  # a newline
        .*?                         # anything between newlines above and below
        (\n|\r\n?)                  # a newline
        \|[ ]-+\|                   # a pipe, a space, multiple dashes and a pipe
    (?=$|\r{3}|\n{3}|(\r\n){3})     # end of string or followed by 3 newline chars
~sx';
preg_match_all($pat,$str,$res);
$blocks = $res[0];
print_r($blocks);

ただし、コンテンツがどのように見えるかを正確に推測するのは難しいため、これが最もエレガントな方法であるか、信頼できる方法であるかはわかりません。

于 2012-11-16T02:48:36.413 に答える
0

オプションの改行を一致させるには、を使用してみてください'/\n(\n{1,})?/'。これは最初の改行と一致し、存在する場合は追加の行と一致します。

これを考慮すると、あなたの答えは次のようになります。

preg_split("/\n(\n{1,})?/", $text)

これにより、テキストが改行で分割されます。

于 2012-11-16T01:52:41.473 に答える
0

ブロックの通常の行とブロックの最初または最後の行を区別する信頼できる方法がないため、問題を解決することは不可能です。

私はすべてロバストネス原則に賛成ですが、これは、データを壊さないようにユーザーをトレーニングする必要がある状況の1つです。カンマを任意に削除したユーザーからのCSV形式のデータを受け入れることはできませんでした。これは、基本的にここでも同じシナリオです。

于 2012-11-16T01:53:13.043 に答える