[SOLVED] ereg_replace for line feeds

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
charp
Forum Commoner
Posts: 85
Joined: Sun Oct 26, 2003 3:00 pm
Location: Rancho Cucamonga, Calif. USA

[SOLVED] ereg_replace for line feeds

Post by charp »

I hear ereg is a difficult to master function, but it's particularly frustrating when you know nothing.

Here's my goal: when a user enters some text into a textbox form (like posting this message) and presses the enter key twice to create a new paragraph, I'd like to replace those two enters with some HTML tags like </p><p>.

I found this online at the php.net site:

Code: Select all

<?php
 $news = ereg_replace("\r?\n\r?\n", "</p><p>", $news);
 $news = ereg_replace("\r?\n", "<br />", $news);
 $news = "<p>".$news."</p>";
?>
Two problems with this code:
1. I don't understand the syntax of "r?\n\r?\n".
2. It doesn't work for me.

As far as I can determine from online resources, Macs and PCs issue line feeds differently and I do want this code to be cross-platform compatible. I thought they were \r\n and \n\r but I may not be correct.

I'm also reading that preg_replace is a faster option in most circumstances, but I can't determine if the same syntax is used for both preg and ereg.

Can anyone shed a bit of light on this subject for me? Point me to some beginner friendly resources?

Thanks!
Last edited by charp on Tue Jul 06, 2004 1:18 pm, edited 1 time in total.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

try

Code: Select all

$news = '<p>'.ereg_replace('[\r\n]+','</p><p>',$news).'</p>'
redmonkey
Forum Regular
Posts: 836
Joined: Thu Dec 18, 2003 3:58 pm

Post by redmonkey »

feyd wrote:try

Code: Select all

$news = '<p>'.ereg_replace('[\r\n]+','</p><p>',$news).'</p>'
The [\r\n]+ requires double quotes....

Code: Select all

$news = '<p>'.ereg_replace("[\r\n]+",'</p><p>',$news).'</p>';
I figured it may be a good idea to still preserve line endings incase you want to offer an edit facility so something like.....

Code: Select all

$news = <<<EOF
Here is some news

Followed by a double return to start a new paragraph
then a single return to signify a new line.

Then a double return to start another new paragraph
EOF;

$news = '<p>' . preg_replace('/(<br \/>)$(.*?)^\\1/sm', '$2</p><p>', nl2br($news)) . '</p>';
echo $news;
...should (untested) output as....

Code: Select all

&lt;p&gt;Here is some news
&lt;/p&gt;&lt;p&gt;
Followed by a double return to start a new paragraph&lt;br /&gt;
then a single return to signify a new line.
&lt;/p&gt;&lt;p&gt;
Then a double return to start another new paragraph&lt;/p&gt;
Which should be able to reverted back to original state by....

Code: Select all

$search = array('<br />', '</p><p>');
$news = substr(str_replace($search, '', $news), 3, -4);
echo $news;
kettle_drum
DevNet Resident
Posts: 1150
Joined: Sun Jul 20, 2003 9:25 pm
Location: West Yorkshire, England

Post by kettle_drum »

Or since you seem to find regex hard and since you can do things in many different ways in php, heres an alternative:

Code: Select all

$string = str_replace("<br>", "</p><p>", nl2br($string));
User avatar
charp
Forum Commoner
Posts: 85
Joined: Sun Oct 26, 2003 3:00 pm
Location: Rancho Cucamonga, Calif. USA

Post by charp »

Okay. This is great stuff -- thanks to all. However, a little learning has led to more questions.

From feyd and redmonkey:
I tried

Code: Select all

<?php
$news = '<p>'.ereg_replace("[\r\n]+",'</p><p>',$news).'</p>';
?>
but double and single "enters" generated new paragraphs. Is this a Mac thing or are single and double "enters" identical? Can anyone help explain the differences between \r\n, \n, \n\r, etc.?

From redmonkey:
Can you help me understand this code:

Code: Select all

<?php
$news = '<p>' . preg_replace('/(<br \/>)$(.*?)^\\1/sm', '$2</p><p>', nl2br($news)) . '</p>';
?>
I know how nl2br works and I can follow the part where the leading and trailing <p> tags are added, but I'm clueless on most everything before that function and preg_replace.

Thanks again! This forum is awesome, which means its members are top notch.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

if you want two or more carriage-return sets to make a new paragraph:

Code: Select all

$news = "this is a\r\n\r\ntest of \n\n\r paragraph\r\rcontrol";
echo '<p>'.preg_replace(array("#\r?\n\r?|\r([^\n])#","#\n{2,}#"),array("\n\\1",'</p><p>'),$news).'</p>';
output

Code: Select all

&lt;p&gt;this is a&lt;/p&gt;&lt;p&gt;test of &lt;/p&gt;&lt;p&gt; paragraph control&lt;/p&gt;
from what I remember only Windows uses both, Mac's use \r and *nix uses \n..
redmonkey
Forum Regular
Posts: 836
Joined: Thu Dec 18, 2003 3:58 pm

Post by redmonkey »

charp wrote:From redmonkey:
Can you help me understand this code:

Code: Select all

<?php
$news = '<p>' . preg_replace('/(<br \/>)$(.*?)^\\1/sm', '$2</p><p>', nl2br($news)) . '</p>';
?>
I know how nl2br works and I can follow the part where the leading and trailing <p> tags are added, but I'm clueless on most everything before that function and preg_replace.
The preg_replace function is defined as preg_replace(PatternToMatch, Replacement, Subject)

In this case it breaks down as....

Pattern to match = '/(<br \/>)$(.*?)^\\1/sm'
Replacement = '$2</p><p>'
Subject = nl2br($news))

The pattern to match is broken down as follows....

(<br \/>) = The parenthesis defines the enclosed as a subpatterrn, the '<br \/>' is a literal match for the <br /> string the extra \ you see is used to escape the /.

$ = end of line.

(.*?) = The . character means 'anything' while the *? means zero or more times again this is defined as a subpattern. Actually slightly more acurate would have been (.{1,2})


^ = Begining of a line.

\\1 = A look back to the 1st subpattern.

There are also two modifiers used here (m & s) at the end of the pattern which are....

m = multiline mode, which essentially means that the ^ and $ characters match the begining and end of each line respectively. The default behavior is to match only the start and end of the string.

s = the . character matches evrything including newlines. The default behavior is to match everything except new lines.


So the whole search pattern reads....

look for <br /> at the end of a line, followed by any character zero or more times (as we are at the end of the it can only be carriage returns or line feeds), followed by the start of a line followed by the same thing as subpattern 1.

The replacement is slightly easier, the $2 is refering to the 2nd subpattern of search pattern (in our case is the line feeds/carriage returns).

And I assume the subject is already understood.
User avatar
charp
Forum Commoner
Posts: 85
Joined: Sun Oct 26, 2003 3:00 pm
Location: Rancho Cucamonga, Calif. USA

Post by charp »

feyd, thanks for your replies. The last example really helped to clear things up for me. Much appreciated.

redmonkey, that was an awesome explanation! But tell me, what sadist wrote the syntax for regular expressions???? Evil, pure evil.
Post Reply