2010-11-20 47 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