最初に下降パーサーを使用すると、常により適切に制御できます。
正規表現ソリューション全体を使用すると、エラーをスキップしたり、少なくとも続行
して無駄になったりしないようにすることができます。
あなたのフォーマットは非常に単純であり、内部再帰を実行できるエンジンは、
少なくともあなたにアウトターマッチを与えることができます。言語再帰を使用すると、その正規表現を再入力して
、コアを解析できます。
私はPHPの専門家ではありませんが、正規表現の再帰と言語レベルのeval()をサポートしている場合
は、ソーステキストに配列構造を挿入できます。
次に、文字列を評価して、パラメータを含むネストされた配列イメージを作成します。
私は実際にあなたのテキストを約12行のPerlの配列に変換しました
が、興味深いときに追加しました。
これがPerlのサンプルです。その唖然としたので、その読みやすい。それはあなたにphpでそれを試すためのいくつかのインスピレーションを与えるかもしれません(それがこれらのことをすることができるなら)。私が言ったように、私はPHPの専門家ではありません。
use Data::Dumper;
my $str = '
asdf("asg")
isNumeric(right(trim(contract_id),1))
var = \'aqfbasdn\'
isNumeric(right(trim ( ,contract_id,),-1, j( ) ," ", bob, george(five(four, two))))
';
my $func = '\w+'; # Allowed characters (very watered down)
my $const = '[\w*&^+-]+';
my $wspconst = '[\w*&^+\s-]+';
my $GetRx = qr~
\s*
( # 1 Recursion group
(?:
\s* ($func) \s*
[(]
(?: (?> (?: (?!\s*$func\s*[(] | [)] ) . )+ )
| (?1)
)*
[)]
)
)
~xs;
my $ParseRx = qr~
( # 1 Recursion group
(?:
\s* ($func) \s* # 2 Function name
[(]
( # 3 Function core
(?: (?> (?: (?!\s*$func\s*[(] | [)] ) . )+ )
| (?1)
)*
)
[)]
# OR..other stuff
# Note that this block of |'s is where
# to put code to parse constants, strings,
# delimeters, etc ... Not much done, but
# here is where that goes.
# -----------------------------------------
| \s*["'] ($wspconst) ["']\s* # 4,5 Variable constants
| \s* ($const) \s*
# Lastly, accept empty parameters, if
| (?<=,) # a comma behind us,
| (?<=^)(?!\s*$) # or beginning of a new 'core' if actually a paramater.
)
)
~xs;
##
print "Source string:\n$str\n";
print "=======================================\n";
print "Searching string for functions ...\n";
print "=======================================\n\n";
while ($str =~ /$GetRx/g) {
print "------------------\nParsing:\n$1\n\n";
my $res = parse_func($1);
print "String to be eval()'ed:\n$res\n\n";
my $hashref = eval $res.";";
print "Hash from eval()'ed string:\n", Dumper( $hashref ), "\n\n";
}
###
sub parse_func
{
my ($core) = @_;
$core =~ s/$ParseRx/ parse_callback($2, $3, "$4$5") /eg;
return $core;
}
sub parse_callback
{
my ($fname, $fbody, $fconst) = @_;
if (defined $fbody) {
return "{'$fname'=>[" . (parse_func( $fbody )) . "]}";
}
return "'$fconst'"
}
出力
Source string:
asdf("asg")
isNumeric(right(trim(contract_id),1))
var = 'aqfbasdn'
isNumeric(right(trim ( ,contract_id,),-1, j( ) ," ", bob, george(five(four, two))))
=======================================
Searching string for functions ...
=======================================
------------------
Parsing:
asdf("asg")
String to be eval()'ed:
{'asdf'=>['asg']}
Hash from eval()'ed string:
$VAR1 = {
'asdf' => [
'asg'
]
};
------------------
Parsing:
isNumeric(right(trim(contract_id),1))
String to be eval()'ed:
{'isNumeric'=>[{'right'=>[{'trim'=>['contract_id']},'1']}]}
Hash from eval()'ed string:
$VAR1 = {
'isNumeric' => [
{
'right' => [
{
'trim' => [
'contract_id'
]
},
'1'
]
}
]
};
------------------
Parsing:
isNumeric(right(trim ( ,contract_id,),-1, j( ) ," ", bob, george(five(four, two))))
String to be eval()'ed:
{'isNumeric'=>[{'right'=>[{'trim'=>['' ,'contract_id','']},'-1',{'j'=>[ ]} ,' ','bob',{'george'=>[{'five'=>['four','two']}]}]}]}
Hash from eval()'ed string:
$VAR1 = {
'isNumeric' => [
{
'right' => [
{
'trim' => [
'',
'contract_id',
''
]
},
'-1',
{
'j' => []
},
' ',
'bob',
{
'george' => [
{
'five' => [
'four',
'two'
]
}
]
}
]
}
]
};