问题
Here's what I try to do :
isNumeric(right(trim(contract_id),1))
isNumeric
right
trim
contract_id
1
isNumeric(right(trim(contract_id),1), bob, george(five(four, two)))
isNumeric
right
trim
contract_id
1
bob
george
five
four
two
So basiclly it take a line (let'say trim(var)) and will make an array of it (array(trim => array(var)).
I did try with regex and strpos but no result... I need help. Thanks.
回答1:
First off a descent parser will always give you better control.
A whole regex solution might enable you to skip errors or at least let you continue
and not crap out.
Your format is extremely simple, and an engine that can do internal recursion could at
least get you an outter match. Using language recursion, you could re-enter that regex
enabling you to parse the core.
I'm no php expert, but if it supports regex recursion and language level eval() you
will be able to inject an array construct into the source text.
Then eval the string to create an nested array image, complete with parameters.
I actually converted your text to an array in about 12 lines of Perl, but added to
it when it got interresting.
Here is a Perl sample. Its dumbed down so its readable. It might give you some inspiration to try it in php (if it can do these things). Like I said I'm no php expert.
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'"
}
Output
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'
]
}
]
}
]
}
]
};
来源:https://stackoverflow.com/questions/10624370/how-to-parse-a-line-and-result-in-array-stuck