Re: RE: My eregi() code will not work.
| From: | Zak Greant | Date: | Sat, 03 Jun 2000 00:13:50 +0000 |
| Subject: | Re: RE: My eregi() code will not work. | ||
| References: | 1 | Groups: | php.general |
| Request: | Send a blank email to php-general+get-934@lists.php.net to get a copy of this message | ||
Hi Ted,
Splitting this type of string into an array based using a single eregi function is an impossible (afaik) task. However, it could be done using the Perl-style regular expression functions.
In any case, lets start with why the code does not work:
eregi("(<br>)", $Note, $matches);This regular expression "(<br>)" will only match a single <br> tag. To make the regex match a complete line that ends with one or more break tags, then your expression should be something like "(.+(<br>)+)". The brackets serve two purposes: The first is that they group the expression inside together. The second is that any text that matches the regular expression inside the brackets is placed into a special register. Depending on what regex function you are using, information from the register can be accessed in different ways. The . character will match any character (well, almost any - in Perl-style regex it won't match newlines or carriage returns unless you set an option in the function that overrides this behavior). The + after it means 'match one or more instances of the preceding character'. The (<br>)+ sequence means 'match one or more instances of <br>' This expression will match a line of text that ends in one or more <br> tags, however, the expression is greedy - it will match the minimum number of <br> tags possible and match the rest of them with the .+ part of the expression. For example, the following code: $text = '<br>This is line 1.<br>This is line 2.<br>This is line 3.<br>This is line 4.'; eregi("(.+(<br>)+)", $text, $matches); : would put the entire contents of $text, except 'This is line 4.' into the second element in the $matches array. This is not really the behavior that we are after.
Print $Note."<br>";
Print $matches[0]."0<br>";
Print $matches[1]."1<br>";
Print $matches[2]."2<br>";
Print $matches[3]."3<br>";
?>
Eregi does not behave in the way that you think it does. The elements in the matches array are based on the numbers of paired brackets in the expression and not on the number of matches to the regular expression.
Using a modified version of your code as an example:
$Note = "<br>This is line 1.<br>This is line 2.<br>This is line 3.<br>";
eregi("(<br>)", $Note, $matches);
# This will contain the entire contents of $Note
Print $matches[0];
/*
The second element of $matches will contain the any text that matched the regular expression between the first set of paired brackets. This should be a single <br> tag.
*/
Print $matches[1];
/*
The third element of $matches will be empty. This is because there is only on set of brackets. If there were a second set of brackets, then any text that matched the regular expression inside of them would be stored in this element.
*/
Print $matches[2];
Hopefully, most of you are still with me! :)
A simpleand most robust way to do this (while maintaining all of the original formatting in the text) is:
<SCRIPT LANGUAGE="PHP">
$text = "<br>This is line 1.<br>This is line 2.<br>This is line 3.<br>";
/* Create a separator and make sure that it does not already exist in the text */
do
{
$separator = '#' . ++$integer . '#';
}
while (strstr ($text, $separator));
/* put a separator behind any sequent of one or more <br> tags */
$text = ereg_replace ('((<br>)+)', "\\1$separator", $text);
/* Create an array using explode */
$lines = explode ($separator, $text);
/* Display the output */
while (list ($key) = each ($lines))
{
$line_no = $key+1;
print "Line $line_no: $lines[$key]";
print htmlentities ("Line $line_no: $lines[$key] (This line has been passed to HTML Entities)") . '<br><br>';
}
</SCRIPT>
Good Luck!
Zak