2013-12-14 41 views
0

我正在嘗試使用preg_match_all從HTML字符串中提取重複的模式。如何使用PHP獲取每個匹配的正則表達式模式

這個問題似乎是我的模式有一個定義的開始和結束,但在它們之間的通配符部分。所以preg_match_all最終只得到最大的比賽,但不是單個比賽。

我的最終目標是將每個<a ...>some text</a>從html字符串中分離出來,並將它們包裝爲:<font ...><a ...>some text</a></font>

但首先關閉我想簡單地成功分離它們每個:

$lvs_regex = "/<a.+<\/a>/" ; 
$lvs_test = "click <a href='...'>AAA</a> now, <a href='...'>BBB</a> later, <a href='...'>CCC</a> tomorrow" ; 

preg_match_all($lvs_regex , $lvs_test , $matches) ; 
for($i = 0 ; $i < count($matches) ; $i++) 
    { print $matches[ $i ][0] . "<br/>" ; 
    } 

,我想返回:

[0] =><a href='...'>AAA</a>

[1] =><a href='...'>BBB</a>

[2] =><a href='...'>CCC</a>

但是我只得到一個匹配:

[0] =><a href='...'>AAA</a> now, <a href='...'>BBB</a> later, <a href='...'>CCC</a>

+1

閱讀上[貪婪](http://www.regular-expressions.info /repeat.html),或者使用否定字符類來匹配兩者之間的非標籤內容。 – mario

+0

爲什麼不使用css規則,而不是將每個鏈接放在''標籤中? –

+0

卡西米爾,文本實際上被髮送到閃光燈,其對html文本有限制。 – dsdsdsdsd

回答

1

也許是這樣的:

$lvs_regex = "/<a.*?<\/a>/" ; 
$lvs_test = "click <a href='...'>AAA</a> now, <a href='...'>BBB</a> later, <a href='...'>CCC</a> tomorrow" ; 

preg_match_all($lvs_regex , $lvs_test , $matches); 

基本上所需的圖案是/<a.*?<\/a>/。這匹配你的字符串中的每一處。

現在,var_dump($matches[0])

array (size=3) 
    0 => string '<a href='...'>AAA</a>' (length=21) 
    1 => string '<a href='...'>BBB</a>' (length=21) 
    2 => string '<a href='...'>CCC</a>' (length=21) 

那就是你想要的回報。

因此,通過與

for($i = 0 ; $i < count($matches[0]) ; $i++) 
{ 
    var_dump($matches[0][ $i ] . "<br/>"); 
} 

下面你現在看到它的匹配每次出現:

string '<a href='...'>AAA</a><br/>' (length=26) 
string '<a href='...'>BBB</a><br/>' (length=26) 
string '<a href='...'>CCC</a><br/>' (length=26) 

--------新的編輯---------

所以,現在你可以修改你的循環,以包裝匹配的每個a標籤。

$result=''; 

for($i = 0 ; $i < count($matches[0]) ; $i++) 
{ 
    $result .= "<font ...>".$matches[0][ $i ] . "</font><br/>"; 
} 

var_dump($result); 

,你會得到

<font ...><a href='...'>AAA</a></font><br/><font ...><a href='...'>BBB</a></font><br/><font ...><a href='...'>CCC</a></font><br/>

----------新的編輯----------

至於建議@Casimir等您可以通過添加bodeary字段在不漏亂標籤上找到相同的「錯誤」或者「不需要的」標籤,加入或退出。

$lvs_regex = "/<a\b.*?<\/a>/" ; 

並通過使用foreach而不是for循環來獲得相同的結果。例如:

foreach($matches[0] as $matches) 
{ 
    $result .= "<font ...>".$matches . "</font><br/>"; 
} 

而一個linkforeach內部行爲,在情況下,你會得到在構造一個深沉的樣子。

+0

這工作...我錯誤地發佈,它沒有工作,因爲我沒有注意到'$匹配[0] ...'你的答案的一部分...對不起,謝謝。 – dsdsdsdsd

+0

添加字邊界避免匹配標籤:'

0
$lvs_regex = "/<a.+<\/a>/U" ; 

$lvs_test = "click <a href='...'>AAA</a> now, <a href='...'>BBB</a> later, <a href='...'>CCC</a> tomorrow" ; 

preg_match_all($lvs_regex , $lvs_test , $matches) ; 
if ($matches) { 
    foreach ($matches[0] as $match) { 
     print $match."\n"; 
    } 
} 

結果是:

<a href='...'>AAA</a> 
<a href='...'>BBB</a> 
<a href='...'>CCC</a> 

使用 'ungreedy' specificator/U

http://www.php.net/manual/fa/reference.pcre.pattern.modifiers.php