【问题标题】:How can I put strings in an array, split by new line?如何将字符串放入数组中,按换行符分割?
【发布时间】:2010-12-01 19:04:03
【问题描述】:

我的数据库中有一个带有换行符的字符串。我想将该字符串转换为一个数组,并且对于每一行,在数组中跳转一个索引位置。

如果字符串是:

My text1
My text2
My text3

我想要的结果是这样的:

Array
(
    [0] => My text1
    [1] => My text2
    [2] => My text3
)

【问题讨论】:

  • 你应该首先规范化换行符,可能。 s($yourString)->normalizeLineEndings() 方法可用于 github.com/delight-im/PHP-Str(MIT 许可下的库),它有许多其他有用的字符串助手。你可能想看看源代码。

标签: php string line-breaks


【解决方案1】:

我一直使用这个非常成功:

$array = preg_split("/\r\n|\n|\r/", $string);

(更新了最后的 \r,感谢@LobsterMan)

【讨论】:

  • 这个答案应该在顶部而不是 Pascal 的。那个不适用于所有情况。!
  • 这就是答案。经验证的是错误的。嗯,hesselbom 也有它......你也可以使用这个等价物: preg_split('/\n|\r/', $string, -1, PREG_SPLIT_NO_EMPTY);为了美丽:) 为什么这是唯一的好答案?因为你无法假设你会得到什么类型的行尾:Mac (\r)、Windows (\r\n) 或 Unix (\n)。
  • \R matches \n, \r\r\n
  • 或更短的/\r?\n/
  • 这个例子是正确的,因为你不能只进行任何基于单个字符的拆分操作。如果你这样做,在 '\r' 或 '\n' 上触发,你将得到一个多余的空行,以防 Windows 以 "\r\n" 结尾。重要的是首先测试两个字符的 Windows 分隔符。
【解决方案2】:

您可以使用explode函数,使用“\n”作为分隔符:

$your_array = explode("\n", $your_string_from_db);

例如,如果你有这段代码:

$str = "My text1\nMy text2\nMy text3";
$arr = explode("\n", $str);
var_dump($arr);

你会得到这个输出:

array
  0 => string 'My text1' (length=8)
  1 => string 'My text2' (length=8)
  2 => string 'My text3' (length=8)


请注意,您必须使用double-quoted string,因此\n 实际上被解释为换行符。
(有关详细信息,请参阅该手册页。)

【讨论】:

  • 您可以使用预定义的常量PHP_EOL,而不是\n
  • 每个人都请小心这个解决方案,因为它不适用于所有换行符。大卫的回答让我获得了最大的成功
  • 您必须在 \n 或\r 处拆分才能处理所有类型的文本 - 这仅适用于 linux 和 windows 换行符。 Mac换行符将被忽略! (\r)
  • 我猜蒂姆斯的回答/评论是不正确的,因为这只会匹配你的系统的换行符,但是当你从其他系统得到有换行符的字符串时,它就不起作用了!电子邮件有这个问题
  • 不,这个答案和这个答案上的 cmets 是错误的!因为这不考虑操作系统换行符,尤其是PHP_EOL。您必须使用preg_split("/\\r\\n|\\r|\\n/", $value)
【解决方案3】:

换行符在不同平台上的定义不同,\r\n、\r 或\n。

使用 RegExp 拆分字符串,您可以使用 \R 匹配所有三个

所以对于你的问题:

$array = preg_split ('/$\R?^/m', $string);

这将匹配 Windows、Mac 和 Linux 上的换行符!

【讨论】:

  • 我也使用了这个,而不是接受的答案和这个线程上的任何其他答案。仅将此评论作为参考。
  • 实际上,这对我不起作用。有时换行符仍然存在于数组键中。
  • 只要使用$array = preg_split ('/\R/', $string);
  • 有时不工作! preg_split("/\r\n|\n|\r/", $string)更好的选择
【解决方案4】:

PHP 已经知道当前系统的换行符。只需使用 EOL 常量。

explode(PHP_EOL,$string)

【讨论】:

  • 是的,但是可以编辑一个文件,或者如本例中的 Windows 中的一个 db 条目,然后在 Linux 系统上使用它。我认为一般的方法更适合。
  • 我不确定这是否正确。如果网页上的文本区域被提交,它可能具有不同的行尾字符,具体取决于用户的浏览器,而不是服务器的操作系统。因此,无论您使用什么操作系统,您都需要能够解析任何内容。这当然是假设您正在做网络工作。
  • 您可能必须在结果字符串上使用trim() 以删除任何无关的空格。
【解决方案5】:

Davids answer 的替代方法更快(更快)是使用str_replaceexplode

$arrayOfLines = explode("\n",
                    str_replace(["\r\n","\n\r","\r"],"\n",$str)
            );

发生了什么:
由于换行符可以有不同的形式,我 str_replace \r\n、\n\r 和 \r 用 \n 代替(并保留原始 \n)。
然后在\n 上爆炸,你就有了一个数组中的所有行。

我在此页面的 src 上做了一个基准测试,并在 for 循环中将行拆分 1000 次,并且:
preg_replace 平均耗时 11 秒
str_replace & explode 平均耗时约 1 秒

my forum上的更多细节和基准信息

【讨论】:

  • 您的论坛链接(以及整个域)似乎已关闭
  • \n\r ...哪个操作系统像这样反向使用换行符?
  • @mickmackusa,我不知道。那是很久以前的事了,我不知道我为什么要那样做。认为我应该删除\n\r
  • 据我所知,您只需要在搜索数组中保留\r\n(就此而言,它不再需要是数组)。我对 preg_ 慢 11 倍的说法很感兴趣。您没有包含您使用的模式。您上面的 sn-p 对输入进行了 4 次传递。一个好的preg_ 技术只会使输入通过一次。正则表达式并不以其速度而闻名,但我认为您的主张需要证实。如果您要在回答中保留此性能声明,请发布您的基准详细信息。
【解决方案6】:

大卫:很好的方向,但你错过了\r。这对我有用:

$array = preg_split("/(\r\n|\n|\r)/", $string);

【讨论】:

  • 捕获组不是必须的。
【解决方案7】:

您不需要 preg_* 函数、preg 模式或 str_replace 等 .. 以通过换行符成功地将字符串分解为数组。在所有情况下,无论是 Linux/Mac 还是 m$,都可以。

<?php 

 $array = explode(PHP_EOL, $string);
 // ...  
 $string = implode(PHP_EOL, $array);

?>

PHP_EOL 是一个常量,用于保存服务器平台使用的换行符。

【讨论】:

  • 该文件可能来自具有不同新行的另一个系统,特别是在使用 PHP 的网络环境中
  • 这正是这个常量存在的原因......并处理了这个特定问题。
  • 如果您从 windows 获取文件,它与从 unix 或 mac 获取的文件不匹配,对吧?
  • 如果您一直在使用纯 utf-8,无处不在,通常包括 utf8 文件,并且您的代码中除了 PHP_EOL 用于换行检测之外别无其他,它将按照描述进行匹配,并且不会发生意外的行为。请记住,不仅仅是我大喊大叫并声称这一点。 PHP_EOL 的可用性得到了充分证实。
  • 在您的情况下,如果源来自其他地方并且没有很好地形成,无论如何,如果您使用 str_replace (比正则表达式更快)可能会更好。 ...总而言之,无论是正则表达式。或 str_replace 或 PHP_EOL,有一句很好的老句子说:“如果它有效 - 不要碰它!”。 :)
【解决方案8】:

StackOverflow 不允许我对 hesselbom 的回答发表评论(声誉不够),所以我要添加自己的...

$array = preg_split('/\s*\R\s*/', trim($text), NULL, PREG_SPLIT_NO_EMPTY);

这对我来说效果最好,因为它还自动消除了前导(第二个 \s*)和尾随(第一个 \s*)空格,并且还跳过了空白行(PREG_SPLIT_NO_EMPTY 标志)。

-= 选项 =-

如果您想保留前导空格,只需去掉第二个 \s* 并将其改为 rtrim()...

$array = preg_split('/\s*\R/', rtrim($text), NULL, PREG_SPLIT_NO_EMPTY);

如果您需要保留空行,请去掉 NULL(它只是一个占位符)和 PREG_SPLIT_NO_EMPTY 标志,就像这样......

$array = preg_split('/\s*\R\s*/', trim($text));

或者保留前导空格和空行...

$array = preg_split('/\s*\R/', rtrim($text));

我看不出有什么理由让你一直想保留尾随空格,所以我建议将第一个 \s* 留在那里。但是,如果您只想用新行分割(如标题所示),这很简单(如 Jan Goyvaerts 所述)...

$array = preg_split('/\R/', $text);

【讨论】:

    【解决方案9】:
    explode("\n", $str);
    

    "(而不是 ')非常重要,否则将不会解释换行符。

    【讨论】:

      【解决方案10】:
      <anti-answer>
      

      正如其他答案所指定的,请务必使用 explode 而不是 split,因为从 PHP 5.3.0 开始,split 已被弃用。即以下是不是您想要的方式:

      $your_array = split(chr(10), $your_string);
      

      LF = "\n" = chr(10), CR = "\r" = chr(13)

      </anti-answer>
      

      【讨论】:

        【解决方案11】:

        这个页面上有很多直接和间接的答案,还有一些关于 cmets 的好建议,但是没有一个答案可以代表我在自己的项目中会写什么。

        PHP 转义序列\R 文档:https://www.php.net/manual/en/regexp.reference.escape.php#:~:text=line%20break,\r\n

        代码:(Demo)

        $string = '
        My text1
        
        My text2
        
        
        My text3
        
        
        ';
        
        var_export(
            preg_split('/\R+/', $string, 0, PREG_SPLIT_NO_EMPTY)
        );
        

        输出:

        array (
          0 => 'My text1',
          1 => 'My text2',
          2 => 'My text3',
        )
        

        OP 没有提到从行中修剪水平空白字符,因此没有期望删除 \s\h 同时在可变(与系统无关的)新行上爆炸。

        虽然PHP_EOL 是明智的建议,但当换行符序列来自另一个操作系统时,它缺乏适当地分解字符串的灵活性。

        使用非正则表达式分解往往不太直接,因为它需要字符串准备。此外,如果需要删除不需要的空白行,则可能会在爆炸后进行清理。

        使用\R+(一个或多个连续换行序列)和PREG_SPLIT_NO_EMPTY 函数标志将在一个简洁的函数调用中提供一个无间隙、索引数组。有些人对正则表达式有偏见,但这是为什么应该使用正则表达式的完美案例。如果出于正当理由(例如,您正在处理数十万个数据点)而担心性能,那么请继续投资于基准测试和微优化。除此之外,只需使用这一行代码,让您的代码简洁、健壮且直接。

        【讨论】:

          【解决方案12】:

          对于任何试图在 crontab 中显示 cronjob 并对如何分隔每一行感到沮丧的人,请使用 explode:

          $output = shell_exec('crontab -l');
          $cron_array = explode(chr(10),$output);
          

          使用 '\n' 似乎不起作用,但 chr(10) 效果很好:D

          希望这可以避免一些人头疼。

          【讨论】:

          • 嗨,杰夫,欢迎来到 SO。您应该将其重写为问答,而不是对其他人问题的回答。这是一个问答网站,不是一般论坛。查看常见问题解答 - stackoverflow.com/faq
          • 使用'\n'不起作用,因为转义序列不解释为单引号,您需要使用双引号代替:"\n"而不是'n'阅读php.net/manual/en/language.types.string.php
          【解决方案13】:

          你可以用这个:

           \str_getcsv($str,PHP_EOL);
          

          【讨论】:

            【解决方案14】:

            这就是我的方式:

            $lines = preg_split('/[\r\n]+/', $db_text, NULL, PREG_SPLIT_NO_EMPTY);
            

            这也将跳过所有空行。

            【讨论】:

              【解决方案15】:

              您可以执行 $string = nl2br($string) 以便将换行符更改为

              <br />. 
              

              这样系统使用\r\n还是\n或者\r都无所谓

              然后你可以将它输入到一个数组中:

              $array = explode("<br />", $string);
              

              【讨论】:

              • 注意:nl2br 不会替换换行符...它只会在每个换行符之前插入一个换行符。因此,除第一个以外的所有数组项都将以换行符开头。如果这对您来说无关紧要,那么这种方法是最快的。如果这确实重要,Jakar's answer 是最快的。
              • 非正则表达式技术的性能优势可能是真实的,但目前不包括 Reed 的基准测试详细信息。细节/结果可能不实。
              【解决方案16】:
              $str = "My text1\nMy text2\nMy text3";
              $arr = explode("\n", $str);
              
              foreach ($arr as $line_num => $line) {
                  echo "Line #<b>{$line_num}</b> : " . htmlspecialchars($line) . "<br />\n";
              }
              

              真正的数组:

              $str = "My text1\nMy text2\nMy text3";
              $arr = explode("\n", $str);
              
              $array = array(); // inisiasi variable array in format array
              
              foreach ($arr as $line) { // loop line by line and convert into array
                  $array[] = $line;
              };
              
              print_r($array); // display all value
              
              echo $array[1]; // diplay index 1
              

              在线嵌入:

              body, html, iframe { 
                width: 100% ;
                height: 100% ;
                overflow: hidden ;
              }
              &lt;iframe src="https://ideone.com/vE1gst" &gt;&lt;/iframe&gt;

              【讨论】:

              • 添加一些解释,说明此答案如何帮助 OP 解决当前问题
              【解决方案17】:

              仅使用'base'包也是简单情况的解决方案:

              > s <- "a\nb\rc\r\nd"
              > l <- strsplit(s,"\r\n|\n|\r")
              > l  # the whole list...
              [[1]]
              [1] "a" "b" "c" "d"
              > l[[1]][1] # ... or individual elements
              [1] "a"
              > l[[1]][2]
              [1] "b"
              > fun <- function(x) c('Line content:', x) # handle as you wish
              > lapply(unlist(l), fun)
              

              【讨论】:

                【解决方案18】:

                在 php 文档中找到了这个:

                <?php
                  // split the phrase by any number of commas or space characters,
                  // which include " ", \r, \t, \n and \f
                
                  $keywords = preg_split("/[\s,]+/", "hypertext language, programming");
                  print_r($keywords);
                ?>
                

                【讨论】:

                • 答案肯定会破坏 OP 的文本。这是另一个问题的正确答案;换句话说,这对于这个页面来说是不正确的。
                【解决方案19】:

                这种方法对我总是有效的:

                $uniquepattern="gd$#%@&~#"//Any set of characters which you dont expect to be present in user input $_POST['text'] better use atleast 32 charecters.
                $textarray=explode($uniquepattern,str_replace("\r","",str_replace("\n",$uniquepattern,$_POST['text'])));
                

                【讨论】:

                • 喜欢将咒骂作为代码的一部分。 :) 无论如何,用 \n 替换更简单也更安全(看看其他答案)。
                猜你喜欢
                • 2013-02-15
                • 1970-01-01
                • 2022-07-06
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2015-11-08
                • 1970-01-01
                • 2020-09-06
                相关资源
                最近更新 更多