...

View Full Version : REGEX - Matching the PHP echo statement



RedHouse
04-26-2011, 03:31 PM
I've been racking my head for a while now, thought I'd bring my problem here encase anyone can easily spot how to solve my problem.

I need a regex to match any PHP echo statement. i.e. it must be able to match the following examples below


echo "this is some text";
echo "this is some text with a ; semi colon in the middle";
echo "this is some text with \" double quotes in the middle";
echo 'this is some text with single quotes in the middle';
echo $variable;
echo "string" . $variable;
echo $variable . "string";
echo $variable . 'string';

Here is what I've come up with so far.
This regex matches everything but then fails when you don't use strings in your echo statement but you use variables instead.

$regex = "/echo\s+(.*?[(\".*?(?<!\\\\)\")|('.*?(?<!\\\\)')])*?;/si";

This regex matches variables but then fails when theres a semi colon inside a string.

$regex = "/echo\s+.*?;

Is there one regex which matches all possibilities? I can't see it.

Fou-Lu
04-26-2011, 04:22 PM
Sure, the pattern for echo is always the same: echo{\s{0,}}{stringout};?. So this should match all without any problems: #^echo\s*(.*);?$#U. The last semi colon is technically not necessary in a PHP script, so I added that to the case, though you cannot be certain if its the end of the script or not (since I have no idea what you are doing with this).

RedHouse
04-26-2011, 06:33 PM
Thanks for the reply but with that regex it gobbles up to much as the dot all (.*) is greedy as there is no ? to limit it. I had the semi colon problem being at the end of the code in the back of my mind but didn't want to complicate the matter myself, as I cannot even seem to solve this problem.

Fou-Lu
04-26-2011, 07:28 PM
Oh I see what you mean. I just tested it as well, and while I could get it to work with a preg_match, it would not work with a match all.
Try this instead: #^echo\s*(.*);?\s*$#msiU

RedHouse
04-27-2011, 01:25 PM
Appreciate the effort but it still doesn't seem to match all cases.

Fou-Lu
04-27-2011, 03:36 PM
Appreciate the effort but it still doesn't seem to match all cases.

Post these cases. I matched this against all the ones you have provided using both a preg_match and preg_match_all successfully.
Running against this:


<?php
$str = <<<STRING
echo "this is some text";
echo "this is some text with a ; semi colon in the middle";
echo "this is some text with \" double quotes in the middle";
echo 'this is some text with 'single quotes' in the middle';
echo \$variable;
echo "string" . \$variable;
echo \$variable . "string";
echo \$variable . 'string';
STRING;

$pattern = '#^echo\s*(.*);?\s*$#msiU';
echo 'ALL:';
if (preg_match_all($pattern, $str, $matches))
{
printf("<pre>%s</pre>", print_r($matches, true));
}

echo '<br />EACH:';
$a = explode(PHP_EOL, $str);
foreach ($a AS $item)
{
if (preg_match($pattern, $item, $matches))
{
printf("<pre>%s</pre>", print_r($matches, true));
}
}


?>


Produces these results, which appear to be correct for your description:


ALL:

Array
(
[0] => Array
(
[0] => echo "this is some text";
[1] => echo "this is some text with a ; semi colon in the middle";
[2] => echo "this is some text with \" double quotes in the middle";
[3] => echo 'this is some text with 'single quotes' in the middle';
[4] => echo $variable;
[5] => echo "string" . $variable;
[6] => echo $variable . "string";
[7] => echo $variable . 'string';
)

[1] => Array
(
[0] => "this is some text"
[1] => "this is some text with a ; semi colon in the middle"
[2] => "this is some text with \" double quotes in the middle"
[3] => 'this is some text with 'single quotes' in the middle'
[4] => $variable
[5] => "string" . $variable
[6] => $variable . "string"
[7] => $variable . 'string'
)

)


EACH:

Array
(
[0] => echo "this is some text";
[1] => "this is some text"
)

Array
(
[0] => echo "this is some text with a ; semi colon in the middle";
[1] => "this is some text with a ; semi colon in the middle"
)

Array
(
[0] => echo "this is some text with \" double quotes in the middle";
[1] => "this is some text with \" double quotes in the middle"
)

Array
(
[0] => echo 'this is some text with 'single quotes' in the middle';
[1] => 'this is some text with 'single quotes' in the middle'
)

Array
(
[0] => echo $variable;
[1] => $variable
)

Array
(
[0] => echo "string" . $variable;
[1] => "string" . $variable
)

Array
(
[0] => echo $variable . "string";
[1] => $variable . "string"
)

Array
(
[0] => echo $variable . 'string';
[1] => $variable . 'string'
)

RedHouse
04-27-2011, 04:07 PM
Apologies I thought the examples I provided would be sufficient, here are a couple of cases I found that did not match from my actual code. I added them to the bottom of the test cases.


<?php
$str = '
echo "this is some text";
echo "this is some text with a ; semi colon in the middle";
echo "this is some text with \" double quotes in the middle";
echo \'this is some text with \'single quotes\' in the middle\';
echo $variable;
echo "string" . $variable;
echo $variable . "string";
echo $variable . \'string\';
echo "<div style=\"font-size: 20px; color: #f33; text-align: center;\">
Thanks for your message. We will be in touch shortly</div>";
value="<?php echo $telephone; ?>"
';

$pattern = '#^echo\s*(.*);?\s*$#msiU';
echo 'ALL:';
if (preg_match_all($pattern, $str, $matches))
{
printf("<pre>%s</pre>", print_r($matches, true));
}

echo '<br />EACH:';
$a = explode(PHP_EOL, $str);
foreach ($a AS $item)
{
if (preg_match($pattern, $item, $matches))
{
printf("<pre>%s</pre>", print_r($matches, true));
}
}


?>

Fou-Lu
04-27-2011, 04:32 PM
Okay, I see. Its not just that there is a newline (initially I could get it to work, but when I translated it so I could view it I saw a problem). The end of the &rt; indicates a semi-colon at the end of the line, so PCRE *thinks* its all done resulting in only half of the data.
I'll get back to you on this one then, it won't be as simple as I thought.

RedHouse
04-27-2011, 05:05 PM
Ah thankyou, that makes sense, I didn't realise that the &rt; would be causing the problem. Just didn't understand.

RedHouse
05-13-2011, 12:15 AM
Sorry to revive this, but did you ever make any progress on it?

Fou-Lu
05-13-2011, 01:02 AM
Sorry to revive this, but did you ever make any progress on it?

Nope, I got busy and forgot about it.
Did you get any further?

RedHouse
05-13-2011, 12:20 PM
Na I got stuck so I fudged it, just used two regexes and two preg matches but no worries dude, cheers for your help and effort anyway.

Fou-Lu
05-13-2011, 03:18 PM
Na I got stuck so I fudged it, just used two regexes and two preg matches but no worries dude, cheers for your help and effort anyway.

Haha, ok then I won't bother. Quite glad actually, last I recall I was trying recursion on something that seemingly shouldn't require it.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum