有没有办法解决这个问题:
[one[two]][three]
用正则表达式提取这个?
Array (
[0] => one[two]
[1] => two
[2] => three
答案 0 :(得分:4)
对于PHP,您可以在几乎为您提供所需内容的正则表达式中使用递归:
$s = 'abc [one[two]][three] def';
$matches = array();
preg_match_all('/\[(?:[^][]|(?R))*\]/', $s, $matches);
print_r($matches);
结果:
Array
(
[0] => Array
(
[0] => [one[two]]
[1] => [three]
)
)
对于比这更高级的东西,最好不要使用正则表达式。
答案 1 :(得分:0)
您可以使用循环来应用正则表达式,例如
\[([^\]]*)\]
。\x01
替换为[
,将\x02
替换为]
并输出结果。\[([^\]]*)\]
替换为\x01$1\x02
(警告:假定\x01
并且字符串不使用\x02
。)但我会为这个问题写一个字符串扫描程序:)。
答案 2 :(得分:0)
#!/usr/bin/perl
use Data::Dumper;
@a = ();
$re = qr/\[((?:[^][]|(??{$re}))*)\](?{push@a,$^N})/;
'[one[two]][three]' =~ /$re*/;
print Dumper \@a;
# $VAR1 = [
# 'two',
# 'one[two]',
# 'three'
# ];
不是完全你要求的东西,但它对于(ir)正则表达式扩展是有用的。 (Perl 5.10的(?PARNO)
可以替换(??{CODE})
的用法。)
答案 3 :(得分:0)
在Perl 5.10正则表达式中,您可以使用命名回溯和递归子例程来执行此操作:
#!/usr/bin/perl
$re = qr /
( # start capture buffer 1
\[ # match an opening brace
( # capture buffer 2
(?: # match one of:
(?> # don't backtrack over the inside of this group
[^\[\]]+ # one or more non braces
) # end non backtracking group
| # ... or ...
(?1) # recurse to bracket 1 and try it again
)* # 0 or more times.
) # end buffer 2
\] # match a closing brace
) # end capture buffer one
/x;
print "\n\n";
sub strip {
my ($str) = @_;
while ($str=~/$re/g) {
$match=$1; $striped=$2;
print "$striped\n";
strip($striped) if $striped=~/\[/;
return $striped;
}
}
$str="[one[two]][three][[four]five][[[six]seven]eight]";
print "start=$str\n";
while ($str=~/$re/g) {
strip($1) ;
}
输出:
start=[one[two]][three][[four]five][[[six]seven]eight]
one[two]
two
three
[four]five
four
[[six]seven]eight
[six]seven
six