Exploding CSV file on new line [duplicate] - php

Simple, right? Well, this isn't working :-\
$skuList = explode('\n\r', $_POST['skuList']);

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']);

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']);

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".

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.

try
explode(chr(10), $_POST['skuList']);

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
)

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',
)

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.

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

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?

Have you tried using double quotes?

Not perfect but I think it must be safest. Add nl2br:
$skuList = explode('<br />', nl2br($_POST['skuList']));

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"

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

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.

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];

Try this:
explode(PHP_EOF, $lines);

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

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'])));

Related

Use line-break as separator for an array input?

I've never actually used arrays before, as I've never had to so far (a simple variable has been enough for me), however now I've created a form with a text-area that is meant to POST multiple urls through to my PHP script.
What I want to do is use a line-break in the visitors input to act as a separator for an array input.
For example, the visitor inputs 90 lines of text (all url's), the array breaks each one into a list of 90, and creates an array value for each one.
Any info, advice or comments would be greatly appreciated :)!
Not 100% percent sure what line breaks are used, e.g.:
Windows uses \r\n
Linux uses \n
(old) Macs used \r
However if you know this you can simply do:
$urls = explode("\n", $_POST['urls']);
EDIT
Actually after testing using regex IS faster than first doing a str_replace() and explode.
Look at http://www.php.net/manual/en/function.preg-split.php and as delimiter use new line sign
or see PHP REGEX - text to array by preg_split at line break
be careful about using just \r or \n because every operating system has "new line" defined another way
see answer by Tgr on SO question PHP REGEX - text to array by preg_split at line break
Use explode
$array=explode("\n",$_POST['textarea']);

When do I use PHP_EOL instead of \n and vice-versa ? Ajax/Jquery client problem

I have a php parser that split a given string by line-breaks, doing something like this:
$lines = explode(PHP_EOL,$content);
The parser works fine when working on server side. However, when I pass the content via post by ajax (using jquery's $.post method) the problem arises: line breaks are not recogniezed. So after almost an hour of tests and head-aches I decided to changed PHP_EOL by "\n" and it worked:
$lines = explode("\n",$content);
Now it works! Damn it I lost so much time! Could somebody explain me when use PHP_EOL and "\n" properly, so I can save time in the future? Appreciate your kind answers ;)
The constant PHP_EOL should generally be used for platform-specific output.
Mostly for file output really.
Actually the file functions already transform \n ←→ \r\n on Windows systems unless used in fopen(…, "wb") binary mode.
For file input you should prefer \n however. While most network protocols (HTTP) are supposed to use \r\n, that's not guaranteed.
Therefore it's best to break up on \n and remove any optional \r manually:
$lines = array_map("rtrim", explode("\n", $content));
Or use the file(…, FILE_IGNORE_NEW_LINES) function right away, to leave EOL handling to PHP or auto_detect_line_endings.
A more robust and terser alternative is using preg_split() and a regexp:
$lines = preg_split("/\R/", $content);
The \R placeholder detects any combination of \r + \n. So would be safest, and even work for Classic MacOS ≤ 9 text files (rarely seen in practice).
Obligatory microoptimization note:
While regex has a cost, it's surprisingly often speedier than manual loops and string postprocessing in PHP.
And there are a few classic examples where you should avoid PHP_EOL due to its platform-ambiguity:
Manual generation of network protocol payloads, such as HTTP over fsockopen().
For mail() and MIME construction (which really, you shouldn't do tediously yourself anyway).
File output, if you want to consistently write just Unix \n newlines regardless of environment.
So use a literal "\r\n" combination when not writing to files, but preparing data for a specific context that expects network linebreaks.
PHP_EOL should be used when writing output such as log files.
It will produce the line break specific to your platform.
PHP_EOL is a constant holding the line break character(s) used by the server platform. In the case of Windows, it's \r\n. On *nix, it's \n. You apparently have a Windows server.
If you were on a *nix server, that change wouldn't have fixed it, because it would be \n. If you are sending data to the client (i.e. the browser), you should use \r\n to ensure line breaks are recognized.
PHP_EOL is the line ending used by the server PHP is running on. User submitted content will probably have line ending in whatever format they use. However, instead of exploding on newlines, just using the file() function, it does exactly what you are after.
IMHO using PHP_EOL is preferable
to ensure consistency between PHP and JS handling of line break, you may want to define end-of-line variable in JS using PHP_EOL
var eol = '<?php echo str_replace(array("\n","\r"),array('\\n','\\r'),PHP_EOL) ?>';
afterwards, use eol for splitting submitted textarea content

How to remove line breaks with PHP or JS

I've tried about everything to delete some extra \n characters in a web application I'm working with. I was hoping someone has encountered this issue before and knows what can be causing this. All my JS and PHP files are UTF-8 encoded with no BOM.
And yes I've tried things like
In JS:
text.replace(/\n/g,"")
In PHP:
preg_replace("[\n]","",$result);
str_replace("\n","",$result);
and when I try
text.replace(/\n/g,"")
in the firebug console using the same string I get from the server it works but for reason it doesn't work in a JS file.
I'm desperate, picky and this is killing me. Any input is appreciated.
EDIT:
If it helps, I know how to use the replace functions above. I'm able to replace any other string or pattern except \n for some reason.
Answer Explanation:
Some people do and use what works because it just works. If you are like me and for the record I always like to know why what works WORKS!
In my case:
Why this works? str_replace('\n', '', $result)
And this doesn't? str_replace("\n", '', $result)
Looks identical right?
Well it seems that when you enclose a string with a character value like \n in double quotes "\n" it's seen as it's character value NOT as a string. On the other hand if you enclose it in single quotes '\n' it's really seen as the string \n. At least that is what i concluded in my 3 hours headache.
If what I concluded is a setup specific issue OR is erroneous please do let me know or edit.
In php, use str_replace(array('\r','\n'), '', $string).
I guess the problem is you also have \r's in your code (carriage returns, also displayed as newlines).
In javascript, the .replace() method doesn't modify the string. It returns a new modified string, so you need to reference the result.
text = text.replace(/\n/g,"")
Both of the PHP functions you tried return the altered string, they do not alter their arguments:
$result = preg_replace("[\n]","",$result);
$result = str_replace("\n","",$result);
Strangely, using
str_replace(array('\r','\n'), '', $string)
didn't work for me. I can't really work out why either.
In my situation I needed to take output from the a WordPress custom meta field, and then I was placing that formatted as HTML in a javascript array for later use as info windows in a Google Maps instance on my site.
If I did the following:
$stockist_address = $stockist_post_custom['stockist_address'][0];
$stockist_address = apply_filters( 'the_content', $stockist_address);
$stockist_sites_html .= str_replace(array('\r','\n'), '', $stockist_address);
This did not give me a string with the html on a single line. This therefore threw an error on Google Maps.
What I needed to do instead was:
$stockist_address = $stockist_post_custom['stockist_address'][0];
$stockist_address = apply_filters( 'the_content', $stockist_address);
$stockist_sites_html .= trim( preg_replace( '/\s+/', ' ', $stockist_address ) );
This worked like a charm for me.
I believe that usage of \s in regular expressions tabs, line breaks and carriage returns.

Explode PHP string by new line

Simple, right? Well, this isn't working :-\
$skuList = explode('\n\r', $_POST['skuList']);
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']);
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']);
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".
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.
try
explode(chr(10), $_POST['skuList']);
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
)
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',
)
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.
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
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?
Have you tried using double quotes?
Not perfect but I think it must be safest. Add nl2br:
$skuList = explode('<br />', nl2br($_POST['skuList']));
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"
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);
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.
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];
Try this:
explode(PHP_EOF, $lines);
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);
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'])));

In PHP: If I start a new line while writing a string in my source is it necessary to concatenate the string?

I'm learning PHP and MySQL together from Head First PHP & MySQL and in the book, they often split their long strings (over 80~ characters) and concatenate them, like this:
$variable = "a very long string " .
"that requires a new line " .
"and apparently needs to be concatenated.";
I have no issue with this, but what strikes me odd is that whitespace in other languages usually don't need concatenation.
$variable = "you guys probably already know
that this simply works too.";
I tried this and it worked just fine. Aren't line breaks always interpreted with a space at the end? Even the PHP manual doesn't concatenate in the echo examples if they span over one line.
Should I follow my book's example or what? I can't tell which is more correct or "proper" since both work and the manual even takes a shorter approach. I also would like to know how important is it to keep code under 80 characters in width? I have always been fine with word warp since my monitor is pretty large and I hate my code getting cut short when I have the screen space.
There's 3 basic ways of building multiline strings in PHP.
a. building string via concatenation and embedded newlines:
$str = "this is the first line, with a line break\n";
$str .= "this is the second line, but won't have a break";
$str .= "this would've been the 3rd line, but since there's no line break in the previous line..."`
b. multi-line string assignment, with embedded newlines:
$str = "this is the first line, with a line break\n
this is the second line, because of the line break.
this line will actually is actually part of the second line, because of no newline";
c. HEREDOC syntax:
$str = <<<EOL
this is the first line
this is the second line, note the lack of a newline
this is the third line\n
this is actually the fifth line, because the newline previously isn't necessary.
EOL;
Heredocs are generally preferable for building multi-line strings. You don't have to escape quotes within the text, variables are interpolated within them as if it was a regular double-quoted string, and newlines within the text are honored.
In PHP long strings don't need concatenation but keep in mind that:
$variable = "you guys probably already know
that this simply works too.";
is the equivalent of
$variable = "you guys probably already know\nthat this simply works too.";
The newline is just the same in these 2 examples (if your system uses \n as a newline - Windows uses \r\n).
So to answer your question, no, you don't have to break large strings in many smaller ones. Doing so is just a matter of preference (which I don't really often see).
The 80 char "limit" is throwback to the old days where terminal screens had an 80 char width. If you ever need to edit something in a narrow width terminal, respecting 80 chars can be helpful. However, if longer than 80 char lines wrapping are causing you headaches in your editor, Don't follow that convention.
When you have a multi-line string as in your second example, the string will be exactly as you type it in your editor. If you have a whole bunch of spaces before your retrun char, those will be in your string var. The only exception to this is if your editor is doing line wrapping, then there is not actually a return char in the string, and it won't show up in the variable.
PHP syntax allows literal line feeds in the strings. Your second example equals this:
you guys probably already know[LF][SPACE][SPACE][SPACE][SPACE]that this simply works too.
where [LF] will be \r\n or \n depending on your editor settings. Those redundant spaces may be an issue or not (not everything is HTML), but it's not the same as concatenating.
No.
1) open quotes
2) write as much as you need, adding spaces, tabs, whatever else
3) close quotes.
If you're using the same quotes within, escape them with \
"Jane said \"It's hot today!\"";
or
'Jane said "It\'s hot today!"';

Categories