我有一个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(),但是自从我做了任何真正的正则表达式以来已经有好几年了,所以我无法想出一个可用的解决方案。
“块”的第一行始终包含|和空格,但字段可能包含文本。 “块”的最后一行始终是一个后跟空格的管道,用短划线填充行,以|。结尾。
答案 0 :(得分:0)
要匹配可选换行符,请尝试使用'/\n(\n{1,})?/'
。这与第一个换行符匹配,然后匹配任何其他行(如果存在)。
考虑到这一点,你的答案是:
preg_split("/\n(\n{1,})?/", $text)
。
这将按换行符分割文本。
答案 1 :(得分:0)
您的问题无法解决,因为您没有可靠的方法来区分块的法线和块的第一行或最后一行。
我全都是robustness principle,但这是你必须训练用户不要破坏数据的情况之一。您无法接受来自任意删除逗号的用户的CSV格式数据,而且这里的情况基本相同。
答案 2 :(得分: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);
我不确定这是否是最优雅甚至可靠的方式,因为很难猜出内容的确切含义。