按新行分解PHP字符串

Web*_*net 233 php

简单吧?好吧,这不行: - \

$skuList = explode('\n\r', $_POST['skuList']);
Run Code Online (Sandbox Code Playgroud)

Lar*_*zan 367

最佳实践

正如第一个答案的评论中所提到的,最佳做法是使用PHP常量PHP_EOL,它代表当前系统的EOL(End Of Line).

$skuList = explode(PHP_EOL, $_POST['skuList']);
Run Code Online (Sandbox Code Playgroud)

PHP提供了许多其他非常有用的常量,您可以使用这些常量来使您的代码系统独立,请参阅此链接以查找有用且与系统无关的目录常量.

警告

这些常量使您的页面系统独立,但是当您将常量与存储在另一个系统上的数据一起使用时,从一个系统移动到另一个系统时可能会遇到问题.新系统的常量可能与以前的系统不同,存储的数据可能不再起作用.因此,在存储数据之前完全解析数据以删除任何系统相关部分.

UPDATE

Andreas的评论让我意识到我在这里提出的"最佳实践"解决方案并不适用于所描述的用例:服务器的EOL(PHP)与浏览器(任何操作系统)使用的EOL没有任何关系,但是(浏览器)是字符串的来源.

所以请使用@Alin_Purcaru(三个向下)的解决方案覆盖你的所有基础(并提出他的答案):

$skuList = preg_split('/\r\n|\r|\n/', $_POST['skuList']);
Run Code Online (Sandbox Code Playgroud)

  • 您不能使用PHP_EOL,因为系统和输入源彼此无关.如果用户在Windows中添加新行并且PHP在Linux上运行,结果可能会被破坏. (15认同)
  • 对于这个用例,这个答案是错误的.在这种情况下,不要使用PHP_EOL常量作为输入源(例如用户的浏览器)绝对不是您的系统.使用解决所有不同行结尾的解决方案(来自Alin Purcaru的回答). (7认同)
  • 这是一个新的答案,但它可能是最好的,也是正确的答案 (5认同)

Ali*_*aru 219

涵盖所有案例.不要依赖您的输入来自Windows环境.

$skuList = preg_split("/\\r\\n|\\r|\\n/", $_POST['skuList']);
Run Code Online (Sandbox Code Playgroud)

要么

$skuList = preg_split('/\r\n|\r|\n/', $_POST['skuList']);
Run Code Online (Sandbox Code Playgroud)

  • 如果eol是`\ r \n`,这将导致空数组元素.为了防止这种情况,要么使用:`preg_split('/ \n |\r /',$ _POST ['skuList'],-1,PREG_SPLIT_NO_EMPTY);`(注意当使用那个标志时``\ r \n`变得不必要了)或者简单地将`\ r \n`*放在*\_ r`:`preg_split('/\r \n | \n |\r \n',$ _POST ['skuList'])之前;` (18认同)
  • @AlinPurcaru你能否在答案中澄清(两者,或者两者都没有?)将返回空白而哪些不会? (3认同)
  • @webbiedave PREG_SPLIT_NO_EMPTY很好,但是它将删除空行。这可能是理想的,也可能不是理想的。 (2认同)

Sel*_*t0r 148

尝试"\n\r"(双引号)或只是"\n".

如果您不确定自己拥有哪种类型的EOL,请在爆炸前运行str_replace,将"\n\r"替换为"\n".

  • PHP中的单引号表示"不解析此字符串".这意味着你的控制字符没有被解析,它们被视为文字(不是换行符和回车符,而是实际的,文字'\n\r').使用双引号表示"解析此字符串",因此将解析您的控制字符.+1 (50认同)
  • 考虑PHP*行尾*常量:`PHP_EOL`. (20认同)
  • `/ N/r`?我知道OP写道,但正确的windows eol是`\ r \n` (17认同)
  • 只要忽略\ r \n,最后使用它的操作系统没有\n是OS9(http://en.wikipedia.org/wiki/Newline#Representations).因此,这将给你最好的结果:`explode("\n",str_replace("\ r",'',$ string)); (3认同)

Spu*_*ley 13

这里有很多东西:

  • 您需要使用双引号,而不是单引号,否则转义字符将不会被转义.
  • 正常的顺序\r\n不是\n\r.
  • 根据来源,你可能只是\n没有\r(或甚至在不寻常的情况下,可能只是\r)

鉴于最后一点,您可能会发现preg_split()使用所有可能的变体将为您提供一种更可靠的分割数据的方法explode().但另外,你可以使用explode()just \n,然后trim()用来删除任何\r留下的字符.


ima*_*man 11

这个php函数通过newline爆炸字符串

注意:Windows中的新行是\ r \n,在LinuxUnix中\n
这个函数将所有新行更改为linux模式然后拆分它.
注意空行会被忽略

function splitNewLine($text) {
    $code=preg_replace('/\n$/','',preg_replace('/^\n/','',preg_replace('/[\r\n]+/',"\n",$text)));
    return explode("\n",$code);
}
Run Code Online (Sandbox Code Playgroud)


$a="\r\n\r\n\n\n\r\rsalam\r\nman khobam\rto chi\n\rche khabar\n\r\n\n\r\r\n\nbashe baba raftam\r\n\r\n\r\n\r\n";
print_r( splitNewLine($a) );
Run Code Online (Sandbox Code Playgroud)

产量

Array
(
    [0] => salam
    [1] => man khobam
    [2] => to chi
    [3] => che khabar
    [4] => bashe baba raftam
)
Run Code Online (Sandbox Code Playgroud)


小智 10

尝试

explode(chr(10), $_POST['skuList']);
Run Code Online (Sandbox Code Playgroud)


ros*_*.dk 9

要保留换行符(作为数组中的空白项):

$skuList = preg_split('/\r\n|\n\r|\r|\n/', $_POST['skuList']);`
Run Code Online (Sandbox Code Playgroud)

这可以处理不常见的 \n\r 以及常见的 \n\r、\n 和 \r。请注意,@Alin_Purcaru 的解决方案非常相似,但不处理 \n\r。

要删除换行符(数组中没有空白项):

$skuList = preg_split('/[\r\n]+/', $_POST['skuList']);
Run Code Online (Sandbox Code Playgroud)

PHP 测试
这些表达式已在以下操作系统上进行了测试:ubuntu-20.04、ubuntu-18.04、windows-2022、windows-2019、windows-2016、macos-11、macos-10.15 以及以下 PHP 版本:8.0、 7.4、7.3、7.2、7.1、7.0

这是PHP测试类:
https://github.com/rosell-dk/exec-with-fallback/blob/main/tests/LineSplittingTest.php

一个成功的 CI 在运行这些测试的项目上运行:
https://github.com/rosell-dk/exec-with-fallback/actions/runs/1520070091

原理的 Javascript 演示
这里有一些类似正则表达式的 javascript 演示(我使用 N 和 R 而不是 \n 和 \r)。

保留换行符演示:https://regexr.com/6ahvl
删除换行符演示:https://regexr.com/6ai0j

PS:目前 regexr 中存在一个错误,导致首次加载时显示“错误”。编辑表达式使错误消失


Rus*_*ias 8

\n放在双引号中:

explode("\n", $_POST['skuList']);

在单引号中,如果我没记错的话,这被视为\n分开处理。


And*_*dge 6

对于新的产品系列,它只是

$list = explode("\n", $text);
Run Code Online (Sandbox Code Playgroud)

对于新行和回车(如在Windows文件中),它就像您发布的那样.你的skuList是文本区吗?

  • 需要双引号. (2认同)

mic*_*usa 5

如果内容可能是在系统之外生成的,那么您的系统使用什么作为换行符并不重要。

收到所有这些答案后,我很惊讶,没有人简单地建议使用\R转义序列。只有一种方式我会考虑在我自己的项目中实现这一点。 \R提供最简洁直接的方法。

https://www.php.net/manual/en/regexp.reference.escape.php#:~:text=line%20break:%20matches%20\n,%20\r%20and%20\r\n

代码:(演示

$text = "one\ntwo\r\nthree\rfour\r\n\nfive";

var_export(preg_split('~\R~', $text));
Run Code Online (Sandbox Code Playgroud)

输出:

array (
  0 => 'one',
  1 => 'two',
  2 => 'three',
  3 => 'four',
  4 => '',
  5 => 'five',
)
Run Code Online (Sandbox Code Playgroud)