【问题标题】:preg_match_all syntax problempreg_match_all 语法问题
【发布时间】:2011-04-14 14:20:14
【问题描述】:
preg_match 语法有问题
在页面中我需要找到类似的东西
$first = '/>http:\/\/www.(.*?)\/(.*?)\</';
$second = '/="http:\/\/www.(.*?)\/(.*?)"/';
如何将两者结合起来?
有点像
$regex = '/(?="|>)http:\/\/www.(.*?)/(.*?)(?"|\<)/';
抱歉,这方面不太好。
【问题讨论】:
标签:
php
regex
preg-match-all
【解决方案1】:
这看起来对我来说是正确的:
/(?:="|>)http:\/\/www\.(.*?)\/(.*?)["<]/i
请注意一些小的更正:您的非捕获组语法有点偏离(应该是 (?:pattern) 而不是 (?pattern)),您还需要转义 . 和 /。
我也不确定(.*?)\/(.*?) 是否完全按照您的想法进行;除非您需要 / 字符,否则我可能会将其替换为 (.*?)。
【解决方案2】:
这是一个有趣的想法。
使用/(?:(=")|>)http:\/\/www\.(.*?)\/(.*?)(?(1)"|<)/sg 循环查找下一个搜索。每次提取变量 $2 和 $3。这使用了条件。
或者,在全部匹配中使用/(?|(?<==")http:\/\/www\.(.*?)\/(.*?)(?=")|(?<=>)http:\/\/www\.(.*?)\/(.*?)(?=<))/sg。这使用分支重置。数组将成对累积 ($cnt++ % 2)。
取决于你所说的组合是什么意思。
一个 perl 测试用例:
use strict;
use warnings;
my $str = '
<tag asdf="http://www.some.com/directory"/>
<dadr>http://www.adif.com/dir</dadr>
';
while ( $str =~ /(?:(=")|>)http:\/\/www\.(.*?)\/(.*?)(?(1)"|<)/sg )
{
print "'$2' '$3'\n";
}
print "--------------\n";
my @parts = $str =~ /(?|(?<==")http:\/\/www\.(.*?)\/(.*?)(?=")|(?<=>)http:\/\/www\.(.*?)\/(.*?)(?=<))/sg;
my $cnt = 0;
for (@parts)
{
print "'$_' ";
if ($cnt++ % 2) {
print "\n";
}
}
__END__
输出:
'some.com' 'directory'
'adif.com' 'dir'
--------------
'some.com' 'directory'
'adif.com' 'dir'