我在这样的字符串中存储了php代码((数组定义))
$code=' array(
0 => "a",
"a" => $GlobalScopeVar,
"b" => array("nested"=>array(1,2,3)),
"c" => function() use (&$VAR) { return isset($VAR) ? "defined" : "undefined" ; },
); ';
Run Code Online (Sandbox Code Playgroud)
有一个正则表达式来提取这个数组?? ,我的意思是我想要类似的东西
$array=(
0 => '"a"',
'a' => '$GlobalScopeVar',
'b' => 'array("nested"=>array(1,2,3))',
'c' => 'function() use (&$VAR) { return isset($VAR) ? "defined" : "undefined" ; }',
);
Run Code Online (Sandbox Code Playgroud)
pD ::我做研究试图找到一个正则表达式但没有找到.
pD2 :: stackoverflow的神,让我现在赏金,我将提供400:3
pD3 ::这将用于内部应用程序,我需要提取一些PHP文件的数组,以部分'处理',我尝试用这个codepad.org/td6LVVme解释
Ham*_*mZa 31
所以这是我提出的MEGA正则表达式:
\s* # white spaces
########################## KEYS START ##########################
(?: # We\'ll use this to make keys optional
(?P<keys> # named group: keys
\d+ # match digits
| # or
"(?(?=\\\\")..|[^"])*" # match string between "", works even 4 escaped ones "hello \" world"
| # or
\'(?(?=\\\\\')..|[^\'])*\' # match string between \'\', same as above :p
| # or
\$\w+(?:\[(?:[^[\]]|(?R))*\])* # match variables $_POST, $var, $var["foo"], $var["foo"]["bar"], $foo[$bar["fail"]]
) # close group: keys
########################## KEYS END ##########################
\s* # white spaces
=> # match =>
)? # make keys optional
\s* # white spaces
########################## VALUES START ##########################
(?P<values> # named group: values
\d+ # match digits
| # or
"(?(?=\\\\")..|[^"])*" # match string between "", works even 4 escaped ones "hello \" world"
| # or
\'(?(?=\\\\\')..|[^\'])*\' # match string between \'\', same as above :p
| # or
\$\w+(?:\[(?:[^[\]]|(?R))*\])* # match variables $_POST, $var, $var["foo"], $var["foo"]["bar"], $foo[$bar["fail"]]
| # or
array\s*\((?:[^()]|(?R))*\) # match an array()
| # or
\[(?:[^[\]]|(?R))*\] # match an array, new PHP array syntax: [1, 3, 5] is the same as array(1,3,5)
| # or
(?:function\s+)?\w+\s* # match functions: helloWorld, function name
(?:\((?:[^()]|(?R))*\)) # match function parameters (wut), (), (array(1,2,4))
(?:(?:\s*use\s*\((?:[^()]|(?R))*\)\s*)? # match use(&$var), use($foo, $bar) (optionally)
\{(?:[^{}]|(?R))*\} # match { whatever}
)?;? # match ; (optionally)
) # close group: values
########################## VALUES END ##########################
\s* # white spaces
Run Code Online (Sandbox Code Playgroud)
我已经发表了一些评论,请注意你需要使用3个修饰符
x::让我发表评论
s:将新线与点
i匹配:匹配不区分大小写
$code='array(0 => "a", 123 => 123, $_POST["hello"][\'world\'] => array("is", "actually", "An array !"), 1234, \'got problem ?\',
"a" => $GlobalScopeVar, $test_further => function test($noway){echo "this works too !!!";}, "yellow" => "blue",
"b" => array("nested"=>array(1,2,3), "nested"=>array(1,2,3),"nested"=>array(1,2,3)), "c" => function() use (&$VAR) { return isset($VAR) ? "defined" : "undefined" ; }
"bug", "fixed", "mwahahahaa" => "Yeaaaah"
);'; // Sample data
$code = preg_replace('#(^\s*array\s*\(\s*)|(\s*\)\s*;?\s*$)#s', '', $code); // Just to get ride of array( at the beginning, and ); at the end
preg_match_all('~
\s* # white spaces
########################## KEYS START ##########################
(?: # We\'ll use this to make keys optional
(?P<keys> # named group: keys
\d+ # match digits
| # or
"(?(?=\\\\")..|[^"])*" # match string between "", works even 4 escaped ones "hello \" world"
| # or
\'(?(?=\\\\\')..|[^\'])*\' # match string between \'\', same as above :p
| # or
\$\w+(?:\[(?:[^[\]]|(?R))*\])* # match variables $_POST, $var, $var["foo"], $var["foo"]["bar"], $foo[$bar["fail"]]
) # close group: keys
########################## KEYS END ##########################
\s* # white spaces
=> # match =>
)? # make keys optional
\s* # white spaces
########################## VALUES START ##########################
(?P<values> # named group: values
\d+ # match digits
| # or
"(?(?=\\\\")..|[^"])*" # match string between "", works even 4 escaped ones "hello \" world"
| # or
\'(?(?=\\\\\')..|[^\'])*\' # match string between \'\', same as above :p
| # or
\$\w+(?:\[(?:[^[\]]|(?R))*\])* # match variables $_POST, $var, $var["foo"], $var["foo"]["bar"], $foo[$bar["fail"]]
| # or
array\s*\((?:[^()]|(?R))*\) # match an array()
| # or
\[(?:[^[\]]|(?R))*\] # match an array, new PHP array syntax: [1, 3, 5] is the same as array(1,3,5)
| # or
(?:function\s+)?\w+\s* # match functions: helloWorld, function name
(?:\((?:[^()]|(?R))*\)) # match function parameters (wut), (), (array(1,2,4))
(?:(?:\s*use\s*\((?:[^()]|(?R))*\)\s*)? # match use(&$var), use($foo, $bar) (optionally)
\{(?:[^{}]|(?R))*\} # match { whatever}
)?;? # match ; (optionally)
) # close group: values
########################## VALUES END ##########################
\s* # white spaces
~xsi', $code, $m); // Matching :p
print_r($m['keys']); // Print keys
print_r($m['values']); // Print values
// Since some keys may be empty in case you didn't specify them in the array, let's fill them up !
foreach($m['keys'] as $index => &$key){
if($key === ''){
$key = 'made_up_index_'.$index;
}
}
$results = array_combine($m['keys'], $m['values']);
print_r($results); // printing results
Run Code Online (Sandbox Code Playgroud)
Array
(
[0] => 0
[1] => 123
[2] => $_POST["hello"]['world']
[3] =>
[4] =>
[5] => "a"
[6] => $test_further
[7] => "yellow"
[8] => "b"
[9] => "c"
[10] =>
[11] =>
[12] => "mwahahahaa"
[13] => "this is"
)
Array
(
[0] => "a"
[1] => 123
[2] => array("is", "actually", "An array !")
[3] => 1234
[4] => 'got problem ?'
[5] => $GlobalScopeVar
[6] => function test($noway){echo "this works too !!!";}
[7] => "blue"
[8] => array("nested"=>array(1,2,3), "nested"=>array(1,2,3),"nested"=>array(1,2,3))
[9] => function() use (&$VAR) { return isset($VAR) ? "defined" : "undefined" ; }
[10] => "bug"
[11] => "fixed"
[12] => "Yeaaaah"
[13] => "a test"
)
Array
(
[0] => "a"
[123] => 123
[$_POST["hello"]['world']] => array("is", "actually", "An array !")
[made_up_index_3] => 1234
[made_up_index_4] => 'got problem ?'
["a"] => $GlobalScopeVar
[$test_further] => function test($noway){echo "this works too !!!";}
["yellow"] => "blue"
["b"] => array("nested"=>array(1,2,3), "nested"=>array(1,2,3),"nested"=>array(1,2,3))
["c"] => function() use (&$VAR) { return isset($VAR) ? "defined" : "undefined" ; }
[made_up_index_10] => "bug"
[made_up_index_11] => "fixed"
["mwahahahaa"] => "Yeaaaah"
["this is"] => "a test"
)
Run Code Online (Sandbox Code Playgroud)
Online regex demo Online php demo
$code='array("aaa", "sdsd" => "dsdsd");'; // fail
$code='array(\'aaa\', \'sdsd\' => "dsdsd");'; // fail
$code='array("aaa", \'sdsd\' => "dsdsd");'; // succeed
// Which means, if a value with no keys is followed
// by key => value and they are using the same quotation
// then it will fail (first value gets merged with the key)
Run Code Online (Sandbox Code Playgroud)
转到Bart Kiers的递归模式以匹配嵌套括号.
因为正则表达式是敏感的,你可能应该使用解析器.@bwoebi在他的回答中做得很好.
bwo*_*ebi 21
即使你要求正则表达式,它也适用于纯PHP.token_get_all这是关键功能.对于正则表达式检查@HamZa的答案.
这里的优点是它比正则表达式更具动态性.正则表达式具有静态模式,而使用token_get_all,您可以在每个令牌之后决定要做什么.它甚至在必要时逃脱单引号和反斜杠,正则表达式不会做什么.
此外,在正则表达式中,即使在评论时,您也有想象它应该做什么的问题; 当您查看PHP代码时,更容易理解的代码是什么.
$code = ' array(
0 => "a",
"a" => $GlobalScopeVar,
"b" => array("nested"=>array(1,2,3)),
"c" => function() use (&$VAR) { return isset($VAR) ? "defined" : "undefined" ; },
"string_literal",
12345
); ';
$token = token_get_all("<?php ".$code);
$newcode = "";
$i = 0;
while (++$i < count($token)) { // enter into array; then start.
if (is_array($token[$i]))
$newcode .= $token[$i][1];
else
$newcode .= $token[$i];
if ($token[$i] == "(") {
$ending = ")";
break;
}
if ($token[$i] == "[") {
$ending = "]";
break;
}
}
// init variables
$escape = 0;
$wait_for_non_whitespace = 0;
$parenthesis_count = 0;
$entry = "";
// main loop
while (++$i < count($token)) {
// don't match commas in func($a, $b)
if ($token[$i] == "(" || $token[$i] == "{") // ( -> normal parenthesis; { -> closures
$parenthesis_count++;
if ($token[$i] == ")" || $token[$i] == "}")
$parenthesis_count--;
// begin new string after T_DOUBLE_ARROW
if (!$escape && $wait_for_non_whitespace && (!is_array($token[$i]) || $token[$i][0] != T_WHITESPACE)) {
$escape = 1;
$wait_for_non_whitespace = 0;
$entry .= "'";
}
// here is a T_DOUBLE_ARROW, there will be a string after this
if (is_array($token[$i]) && $token[$i][0] == T_DOUBLE_ARROW && !$escape) {
$wait_for_non_whitespace = 1;
}
// entry ended: comma reached
if (!$parenthesis_count && $token[$i] == "," || ($parenthesis_count == -1 && $token[$i] == ")" && $ending == ")") || ($ending == "]" && $token[$i] == "]")) {
// go back to the first non-whitespace
$whitespaces = "";
if ($parenthesis_count == -1 || ($ending == "]" && $token[$i] == "]")) {
$cut_at = strlen($entry);
while ($cut_at && ord($entry[--$cut_at]) <= 0x20); // 0x20 == " "
$whitespaces = substr($entry, $cut_at + 1, strlen($entry));
$entry = substr($entry, 0, $cut_at + 1);
}
// $escape == true means: there was somewhere a T_DOUBLE_ARROW
if ($escape) {
$escape = 0;
$newcode .= $entry."'";
} else {
$newcode .= "'".addcslashes($entry, "'\\")."'";
}
$newcode .= $whitespaces.($parenthesis_count?")":(($ending == "]" && $token[$i] == "]")?"]":","));
// reset
$entry = "";
} else {
// add actual token to $entry
if (is_array($token[$i])) {
$addChar = $token[$i][1];
} else {
$addChar = $token[$i];
}
if ($entry == "" && $token[$i][0] == T_WHITESPACE) {
$newcode .= $addChar;
} else {
$entry .= $escape?str_replace(array("'", "\\"), array("\\'", "\\\\"), $addChar):$addChar;
}
}
}
//append remaining chars like whitespaces or ;
$newcode .= $entry;
print $newcode;
Run Code Online (Sandbox Code Playgroud)
Demo at: http://3v4l.org/qe4Q1
应输出:
array(
0 => '"a"',
"a" => '$GlobalScopeVar',
"b" => 'array("nested"=>array(1,2,3))',
"c" => 'function() use (&$VAR) { return isset($VAR) ? "defined" : "undefined" ; }',
'"string_literal"',
'12345'
)
Run Code Online (Sandbox Code Playgroud)
您可以获取数组的数据来获取数组的print_r(eval("return $newcode;"));条目:
Array
(
[0] => "a"
[a] => $GlobalScopeVar
[b] => array("nested"=>array(1,2,3))
[c] => function() use (&$VAR) { return isset($VAR) ? "defined" : "undefined" ; }
[1] => "string_literal"
[2] => 12345
)
Run Code Online (Sandbox Code Playgroud)