2010-11-20 49 views
1
<?php 
$content = " 
{php 
    {php 1 php} 
    {php 2 php} 
    {php 3 php} 
php}"; 

如何获取4个字符串?preg_match搜索

第一:

{php 1 php} 
{php 2 php} 
{php 3 php} 

二:

1 

三:

2 

四:

3 
+12

不应使用正则表达式解析HTML。你应该使用[DOM解析器](http://stackoverflow.com/questions/3577641)而不是 – 2010-11-20 18:16:57

+0

没有野心也改变标题... – Gumbo 2010-11-20 18:21:25

+0

@Pekka,我改变了第一篇文章。现在帮助我 – Isis 2010-11-20 18:25:32

回答

4

虽然你可以用简单的计数器轻松解析这样的输入,但可以使用递归正则表达式来获得你想要的。 (?)一个简单的正则表达式来验证输入将是:

^({php\s*(\d+|(?1)+)\s*php}\s*)$ 

(?1)是递归的比赛,它试图重新匹配所述第一组,这是另一个{php ... php}令牌。我们还在php之间有一个捕获组来捕获其内容。

在你的情况下,你想捕获重叠的结果(实际上,甚至包含其他结果中包含的结果)。这更不美观,但仍然可能,使用前瞻。环视可以捕获组,这样的格局将是:

(?=({php\s*(\d+|(?1)+)\s*php}\s*)) 

结果有两个额外的拍摄组 - 周边的外观空白结果,以及与外{php ... php}整个令牌,但如果使用PREG_PATTERN_ORDER您的预计结果将在第三现在的位置([2]):

[2] => Array 
(
    [0] => {php 1 php} 
      {php 2 php} 
      {php 3 php} 
    [1] => 1 
    [2] => 2 
    [3] => 3 
) 

这里有点更复杂的例子:http://ideone.com/sWWrT

现在,谨慎的强制性字。正如我前面所说,这是一个简单的深度计数器更可读性和可维护性,在这里,除了娱乐用途之外,您不需要真正的正则表达式。

+1

“休闲正规乐队” - 我*喜欢*那!工作很好,谢谢。说到深度计数器,偶然你熟悉[PCRE的标注机制](http://linux.die.net/man/3/pcrecallout)?我想知道PHP是否以某种方式使用了它;你会知道答案吗?它对应于(或多或少)Perl的'(?{...})'正则表达式代码转义。您可以在条件模式的“COND”部分使用标注“(?(COND)YES_PATTERN | NO_PATTERN)”查看深度计数器。 '(COND)'也可以是像'(R)','(R1)','(R2)'或'(R&NAME)'这样的递归测试。这不需要标注支持。 – tchrist 2010-11-20 22:38:10

+0

@tchrist - 谢谢!我相信这与许多口味所提供的“e”标志相同。我对此并不熟悉,因为我从来没有机会使用它 - 我对PHP,Perl或Python知之甚少。另外,我错了 - 一个柜台可以取得一个平衡的代币,但不是在各个层面收集它们。无论哪种方式,我不知何故将其视为代码块的乐趣。 – Kobi 2010-11-21 09:41:15

+0

@tchrist您是否曾经发现代码标注是否可以通过'prere_'接口到'PCRE'? – zx81 2014-06-24 22:14:20

0
$regex = preg_match_all("/({php (\d+) php})+/", $content); 
$regex[0][0] == "{php 1 php}"; 
$regex[0][1] == "{php 2 php}"; 
$regex[0][2] == "{php 3 php}"; 
end($regex)[0] == "1"; 
end($regex)[1] == "2"; 
end($regex)[2] == "3"; 

寻找类似的东西?

+0

我想他也希望它能够抓住嵌套的情况。 – Orbling 2010-11-20 21:24:47

+0

@Orbling:你为什么不向他展示递归正则表达式?我会这样做,但我的母语是Perl,而我一直无法知道如何知道给定的PHP实现链接到哪个版本的PCRE。 *(¿ououλpoqλuɐƨəop)* PCRE在正则表达式中的头部与尾部递归的规则略微不同于Perl的规则,我会害怕这样做是错误的。 **谢谢!** – tchrist 2010-11-20 21:48:03

+0

我不是那么做吗?或者我完全错过了这一点? – 2010-11-20 21:48:04