332

Simple, right? Well, this isn't working :-\

$skuList = explode('\n\r', $_POST['skuList']);
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Ben
  • 60,438
  • 111
  • 314
  • 488
  • 32
    Single quotes mean "don't parse this string". @Select0r's answer is probably what you're looking for. – Ryan Kinal Oct 22 '10 at 13:45
  • 4
    possible duplicate of [how to remove new lines and returns from php string?](http://stackoverflow.com/questions/3986299/how-to-remove-new-lines-and-returns-from-php-string) which already was a duplicate of [Reliably remove newslines from string](http://stackoverflow.com/questions/2274506/reliably-remove-newlines-from-string) and [some others](http://stackoverflow.com/search?q=remove+newlines+from+string+php). – Gordon Oct 22 '10 at 13:46
  • 10
    In addition to the single quotes issued mentioned by others, CRLF pairs are `\r\n` not the other way around. – Powerlord Oct 22 '10 at 14:09
  • 2
    Try to remember that: \R etur \N – l00k Mar 26 '19 at 10:04
  • $skuList = explode("\n\r", $_POST['skuList']); should work. it really depends on how your string variable is wrapped up. could be " " or ' ' for $string = 'abc\n\rdef' use $skuList = explode('\n\r', $string); – nh-labs Jan 14 '21 at 13:26

19 Answers19

548

Best Practice

As mentioned in the comment to the first answer, the best practice is to use the PHP constant PHP_EOL which represents the current system's EOL (End Of Line).

$skuList = explode(PHP_EOL, $_POST['skuList']);

PHP provides a lot of other very useful constants that you can use to make your code system independent, see this link to find useful and system independent directory constants.

Warning

These constants make your page system independent, but you might run into problems when moving from one system to another when you use the constants with data stored on another system. The new system's constants might be different from the previous system's and the stored data might not work anymore. So completely parse your data before storing it to remove any system dependent parts.

UPDATE

Andreas' comment made me realize that the 'Best Practice' solution I present here does not apply to the described use-case: the server's EOL (PHP) does not have anything to do with the EOL the browser (any OS) is using, but that (the browser) is where the string is coming from.

So please use the solution from @Alin_Purcaru to cover all your bases:

$skuList = preg_split('/\r\n|\r|\n/', $_POST['skuList']);
codewario
  • 19,553
  • 20
  • 90
  • 159
Larzan
  • 9,389
  • 3
  • 42
  • 41
  • 24
    You can't use PHP_EOL because the system and the input source have nothing to do with each other. If user put new lines in Windows and the PHP is running on Linux the result may be broken. – barell Jan 25 '16 at 11:33
  • 1
    @barell exactly, thats the situation i describe in the 'warning' part ;) The question did not explicitly state that it is an old input stored in the database. Please read the 'warning' part and you will see that i cover that situation there. – Larzan Jan 26 '16 at 13:12
  • 8
    This answer is just wrong for this use-case. Do not use the PHP_EOL constant in this case as the input source (e.g. the user's browser) is definitely not your system. Use a solution that takes care of all the different line endings (answer from Alin Purcaru). – Andreas May 03 '16 at 08:43
  • So if I switch the server and the EOL PHP settings change, then I have a problem whenever I use this command for text from my database? – Adam Nov 14 '17 at 12:23
  • @Adam yes, you should normalize the strings that you store in your DB and always store them one way or the other, NOT with the systems EOL but one of the two. That way you won't have problems changing systems as all your strings in the DB have the same EOL string. – Larzan Nov 14 '17 at 14:06
306

Cover all cases. Don't rely that your input is coming from a Windows environment.

$skuList = preg_split("/\\r\\n|\\r|\\n/", $_POST['skuList']);

or

$skuList = preg_split('/\r\n|\r|\n/', $_POST['skuList']);
Alin Purcaru
  • 43,655
  • 12
  • 77
  • 90
  • 28
    This will result in empty array elements if the eol is `\r\n`. To prevent that, either use: `preg_split('/\n|\r/', $_POST['skuList'], -1, PREG_SPLIT_NO_EMPTY);` (note that `\r\n` becomes unnecessary when using that flag) or simply put the `\r\n` *before* the `\r`: `preg_split('/\r\n|\n|\r/', $_POST['skuList']);` – webbiedave May 09 '12 at 15:26
  • 3
    @webbiedave PREG_SPLIT_NO_EMPTY is nice, BUT it will delete empty lines. This may or may not be desirable. – jms Feb 21 '13 at 14:30
  • 1
    This pattern would match every letter for me, because it results in success even if nothing is present. "?" means 0 or one time, so it is possible for it to match even if both \r and \n are not present. You say "fixed" but I don't see that. I used /(\r|\n)+/ instead. – Rolf Aug 05 '13 at 14:16
  • 1
    @Rolf It seems I made an edit in a hurry. Corrected it now. What you should use depends on whether you want the empty lines or not in the output. The option from my answer also returns empty lines. – Alin Purcaru Aug 05 '13 at 14:42
  • How about this? `preg_split('/[\r\n]+/', $_POST['skuList']);` (haven't tested it) :) – Rolf Aug 16 '13 at 05:19
  • @Rolf That one would not return the empty lines. – Alin Purcaru Aug 16 '13 at 06:02
  • 3
    @AlinPurcaru Can you clarify in the answer which (both, either, neither?) will return blanks and which will not? – Patrick Sep 05 '13 at 14:24
  • I think this answer should be used instead of the checked answer whenever your text comes from an database. – Adam Nov 14 '17 at 12:27
  • Your expression creates double lines for the (quite unusual) \n\r sequence. To cover that sequence as well, you can use `$skuList = preg_split('/\n\r|\r\n|\n|\r/', $_POST['skuList']);` – rosell.dk Nov 30 '21 at 07:49
  • Demo: https://regexr.com/6ahvl (using N and R instead of \n and \r and using regexr.com, which is javascript engine). This solution preserves line breaks (as blank items in the array) – rosell.dk Nov 30 '21 at 07:58
160

Try "\n\r" (double quotes) or just "\n".

If you're not sure which type of EOL you have, run a str_replace before your explode, replacing "\n\r" with "\n".

Select0r
  • 12,234
  • 11
  • 45
  • 68
  • 57
    Single quotes in PHP mean "don't parse this string". That means your control characters aren't being parsed, they're being taken as literal (not a line break and a carriage return, but actual, literal '\n\r'). Using double quotes means "parse this string", and thus your control characters will be parsed. +1 – Ryan Kinal Oct 22 '10 at 13:44
  • 18
    `/n/r`? I know the OP wrote that but the correct windows eol is `\r\n` – webbiedave May 09 '12 at 15:23
  • 21
    Consider the PHP *end of line* constant: `PHP_EOL`. – Daniel W. May 09 '14 at 06:59
  • Hi everyone, this is definitely the right answer ! I'm wondering why did @Alin Purcaru answer got 44 votes.. It's wrong!!! It's not always working correctly although it seems that it does the job.. So here's my comment for anyone stucking on the same thing – Rafik Bari Jul 29 '14 at 17:29
  • 4
    Just disregard the \r, the last OS to use it without \n was OS9 ( http://en.wikipedia.org/wiki/Newline#Representations ). Therefore this will give you the best results: `explode("\n", str_replace("\r", '', $string));` – DanielM Jan 15 '15 at 15:30
16

It doesn't matter what your system uses as newlines if the content might be generated outside of the system.

I am amazed after receiving all of these answers, that no one has simply advised the use of the \R escape sequence. There is only one way that I would ever consider implementing this in one of my own projects. \R provides the most succinct and direct approach.

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

Code: (Demo)

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

var_export(preg_split('~\R~', $text));

Output:

array (
  0 => 'one',
  1 => 'two',
  2 => 'three',
  3 => 'four',
  4 => '',
  5 => 'five',
)
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
15

Lots of things here:

  • You need to use double quotes, not single quotes, otherwise the escaped characters won't be escaped.
  • The normal sequence is \r\n, not \n\r.
  • Depending on the source, you may just be getting \n without the \r (or even in unusual cases, possibly just the \r)

Given the last point, you may find preg_split() using all the possible variants will give you a more reliable way of splitting the data than explode(). But alternatively you could use explode() with just \n, and then use trim() to remove any \r characters that are left hanging around.

Spudley
  • 166,037
  • 39
  • 233
  • 307
14

try

explode(chr(10), $_POST['skuList']);
Oberdan
  • 304
  • 1
  • 4
  • 9
14

this php function explode string by newline

Attention : new line in Windows is \r\n and in Linux and Unix is \n
this function change all new lines to linux mode then split it.
pay attention that empty lines will be ignored

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

example

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

output

Array
(
    [0] => salam
    [1] => man khobam
    [2] => to chi
    [3] => che khabar
    [4] => bashe baba raftam
)
iman
  • 6,062
  • 1
  • 19
  • 23
  • 1
    There is NO way that I would ever use your snippet. The most direct / sensible technique for your invented string would be `var_export(preg_split('~\R+~', $a, 0, PREG_SPLIT_NO_EMPTY));` Anything else is simply not clever. [Demo](https://3v4l.org/Cv9KR) – mickmackusa Sep 16 '20 at 15:02
8

For a new line, it's just

$list = explode("\n", $text);

For a new line and carriage return (as in Windows files), it's as you posted. Is your skuList a text area?

Andrew Sledge
  • 10,163
  • 2
  • 29
  • 30
8

Place the \n in double quotes:

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

In single quotes, if I'm not mistaken, this is treated as \ and n separately.

Russell Dias
  • 70,980
  • 5
  • 54
  • 71
8

To preserve line breaks (as blank items in the array):

$skuList = preg_split('/\r\n|\n\r|\r|\n/', $_POST['skuList']);`

This handles the unusual \n\r as well as the usual \n\r, \n and \r. Note that the solution from @Alin_Purcaru is very similar, but doesn't handle \n\r.

To remove line breaks (no blank items in the array):

$skuList = preg_split('/[\r\n]+/', $_POST['skuList']);

PHP Tests
These expressions has been tested on the following OS'es: ubuntu-20.04, ubuntu-18.04, windows-2022, windows-2019, windows-2016, macos-11, macos-10.15 and in the following PHP versions: 8.0, 7.4, 7.3, 7.2, 7.1, 7.0

Here is the PHP test class:
https://github.com/rosell-dk/exec-with-fallback/blob/main/tests/LineSplittingTest.php

And a successful CI run on a project that runs those tests:
https://github.com/rosell-dk/exec-with-fallback/actions/runs/1520070091

Javascript demos of the principle
Here are some javascript demos of similar regular expressions (I'm using N and R instead of \n and \r).

Preserve linebreaks demo: https://regexr.com/6ahvl
Remove linebreaks demo: https://regexr.com/6ai0j

PS: There is currently a bug in regexr which causes it to show "Error" when first loaded. Editing the expression makes the error go away

rosell.dk
  • 2,228
  • 25
  • 15
4

Have you tried using double quotes?

piddl0r
  • 2,431
  • 2
  • 23
  • 35
3

Not perfect but I think it must be safest. Add nl2br:

$skuList = explode('<br />', nl2br($_POST['skuList']));
nggit
  • 611
  • 8
  • 8
3

As easy as it seems

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

You just need to pass the exact text "\n" and writing \n directly is being used as an Escape Sequence. So "\\" to pass a simple backward slash and then put "n"

Utsav Barnwal
  • 985
  • 11
  • 14
1

PHP_EOL is ostensibly used to find the newline character in a cross-platform-compatible way, so it handles DOS/Unix issues.

Try this:

$myString = "Prepare yourself to be caught
You in the hood gettin' shot
We going throw hell of blows
got my whole frame froze";

$myArray = explode(PHP_EOL, $myString);

print_r($myArray);
Prince Lionel N'zi
  • 2,510
  • 2
  • 12
  • 27
0

Losing line breaks from posting from input textboxes?
What works faster for me is to copy paste any text or Excel or HTML table type or newline type of data and paste it into a textarea instead of an inputextbox: this keeps the linebreaks intact in the POST.

 <textarea  id="txtArea" name="txtArea" rows="40" cols="170"></textarea>
 <br>
 <input type="submit" value="split lines into array" /> 

in the form receiving file:

 $txtArea ='';  
 $txtArea = $_POST['txtArea'];  
 $TA = $_POST['txtArea'];  
 $string = $TA;  
 $array = preg_split ('/$\R?^/m', $string); 
// or any of these: 
// $array = explode(PHP_EOL,$string);  
// $array = explode("\n", $txtArea); 
 echo "<br>A0: ".$array[0];
 echo "<br>A1: ".@$array[1];
 echo "<br>A2: ".@$array[2];
KarlosFontana
  • 188
  • 2
  • 7
0

Try this:

explode(PHP_EOF, $lines);
Paresh Mayani
  • 127,700
  • 71
  • 241
  • 295
0

First of all, I think it's usually \r\n, second of all, those are not the same on all systems. That will only work on windows. It's kind-of annoying trying to figure out how to replace new lines because different systems treat them differently (see here). You might have better luck with just \n.

0

Here is what worked for me. Tested in PHP 5.6 as well as as PHP 7.0:

    $skuList = str_replace("\\r\\n", "\n", $_POST['skuList']);
    $skuList = str_replace("\\n\\r", "\n", $skuList);

    $skuList = preg_split("/\n/", $skuList);
    print_r($skuList);
codemonkey
  • 7,325
  • 5
  • 22
  • 36
-1

This method always works for me:

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