[英]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.