簡體   English   中英

PHP PCRE匹配文本的“塊”

[英]PHP PCRE matching a “block” of text

我有一個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       |
| ---------------------------------------------------------------|

我需要做的基本上是按照相同的順序將每個“塊”本身隔離開,因此我可以將它們一個接一個地循環。 一個“解決方案”可能正在做

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

但是,如果提交文本的人認為不必要的換行符不屬於並將其刪除,則會產生意外的結果。 我嘗試過使用preg_match_all(),但是自從進行任何真正的正則表達式已經有好幾年了,所以我無法提出一個可用的解決方案。

“塊”的第一行始終包含|。 和空格,但字段可能包含文本。 “塊”的最后一行始終是管道,后跟一個空格,短划線表示該行,以|結尾。

要匹配可選的換行符,請嘗試使用'/\\n(\\n{1,})?/' 這匹配第一個換行符,然后匹配任何其他行(如果存在)。

考慮到這一點,您的答案將是:

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

這將用換行符分隔文本。

您的問題無法解決,因為您沒有可靠的方式來區分塊的正常行和塊的第一行或最后一行。

我全力支持魯棒性原則 ,但這只是其中一種情況,您只需要訓練用戶不要破壞數據即可。 您不能接受來自用戶任意刪除逗號的CSV格式數據,這里的情況基本上是相同的。

如果這是文本文件內容的樣子,我會寫類似

$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);

但是,我不確定這是否是最優雅甚至最可靠的方法,因為很難猜測內容的確切外觀。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM