Reputation: 1619
I am parsing a php file and I want to get an specific variable value from it.
say $str = '$title = "Hello world" ; $author = "Geek Batman"';
I want to get "Geek Batman" given variable say, $author. But I want to do this dynamically.
Let's say from an html form input value so
$myDynamicVar = $_POST['var']; //coming from form in the HTML
//$myDynamicVar = '$title = '; (the user will provide the dollar sign and the equal sign)
$pattern = '/\'. $myDynamicVar . '"(.*?)"/s';
$result = preg_match_all($pattern, $str, $output, PREG_SET_ORDER);
the result is coming out empty, although I know the variable exists. I am assuming it has to do with double quotes and I am not escaping them correctly.
Anyone can help?
Upvotes: 1
Views: 245
Reputation: 255155
It is a bit crazy to parse php code with regular expressions when a proper tokenizer is available:
$str = '$title = "Hello world" ; $author="Geek Batman"';
$tokens = token_get_all('<?php ' . $str);
$state = 0;
$result = null;
foreach ($tokens as $token) {
switch ($state) {
case 0:
if ($token[0] == T_VARIABLE && $token[1] == '$author') {
$state = 1;
}
break;
case 1:
if ($token[0] == T_CONSTANT_ENCAPSED_STRING) {
$result = $token[1];
break 2;
}
break;
}
}
var_dump($result);
Demo: http://ideone.com/bcV9ol
Upvotes: 2
Reputation: 23002
The problem more likely has to do with the special characters that the user enters that have some meaning in regex (mainly the dollar in your case, but maybe other characters too). So you need to escape them (with preg_quote
) so the regex matches a $
instead of interpreting it as end of line
.
(the way you were using to escape the dollar didn't work, it was escaping the quote to close the string, instead of escaping the dollar in the variable contents)
Try the following:
$myDynamicVar = $_POST['var']; //coming from form in the HTML
//$myDynamicVar = '$title = '; (the user will provide the dollar sign and the equal sign)
$pattern = '/'. preg_quote($myDynamicVar) . '"(.*?)"/s';
$result = preg_match_all($pattern, $str, $output, PREG_SET_ORDER);
Upvotes: 1