2017-08-30 66 views
2

我想提取兩個子串之間的子串。問題是它只會提取第一個。我想在我的所有文檔中都這樣做。如何獲取兩個子串之間的子串?

例子:

function getBetween($content,$start,$end){ 
    $r = explode($start, $content); 
    if (isset($r[1])){ 
     $r = explode($end, $r[1]); 
     return $r[0]; 
    } 
    return ''; 
} 

$document = '<a data-id="777777"></a><a data-id="888888"></a><a data-id="99999"></a>'; 
$content = $document; 
$start = '<a data-id="'; 
$end = '"'; 
$data = getBetween($content,$start,$end); 
echo $data; 

$document2 = '<a data-A="AAAAAA"></a><a data-A="BBBBBB"></a><a data-A="CCCCCC"></a>'; 
$content = $document2; 
$start = '<a data-A="'; 
$end = '"'; 
$data2 = getBetween($content,$start,$end); 
echo $data2; 

現在它僅取出777777AAAAA。但我要的是777777AAAAAA888888BBBBBB999999CCCCC

+0

使用http://php.net/manual/en/function.preg-match-all.php – Neodan

+0

我得到了一些麻煩事情了。是否有另一種方法來實現這一結果? – user1708580

回答

2

只需使用preg_match_all功能。

例子:

<?php 
$document = '<a data-id="777777"></a><a data-id="888888"></a><a data-id="99999"></a>'; 
$document2 = '<a data-A="AAAAAA"></a><a data-A="BBBBBB"></a><a data-A="CCCCCC"></a>'; 

$list1 = []; 
$list2 = []; 
preg_match_all('/<a data-id="([^"]+)"/', $document, $list1); 
preg_match_all('/<a data-A="([^"]+)"/', $document2, $list2); 
print_r([$list1, $list2]); 
2

代碼:(Demo

function getBetween($content,$start,$end){ 
    return preg_match_all('/'.preg_quote($start,'/').'\K[^'.preg_quote($end,'/').']*(?='.preg_quote($end,'/').')/',$content,$out)?$out[0]:''; 
} 


$document = '<a data-id="777777"></a><a data-id="888888"></a><a data-id="99999"></a>'; 
$content = $document; 
$start = '<a data-id="'; 
$end = '"'; 
$data = getBetween($content,$start,$end); 
var_export($data); 

$document2 = '<a data-A="AAAAAA"></a><a data-A="BBBBBB"></a><a data-A="CCCCCC"></a>'; 
$content = $document2; 
$start = '<a data-A="'; 
$end = '"'; 
$data2 = getBetween($content,$start,$end); 
var_export($data2); 

輸出:

array (
    0 => '777777', 
    1 => '888888', 
    2 => '99999', 
)array (
    0 => 'AAAAAA', 
    1 => 'BBBBBB', 
    2 => 'CCCCCC', 
) 

我的方法有效地產生這種模式:/<a data-id="\K[^"]*(?=")/返回所需的子字符串作爲全字符串匹配。此模式不僅執行步驟更少,因爲它沒有捕獲組,所以它會返回更小的結果數組。 Pattern Demo Link

preg_quote()用於轉義所有必要的字符,以便變量模式不「中斷」。

$end在圖案中使用兩次 - 一次是在「否定字符類」 [^"]並在「正期待」 (?=")

只是爲了記錄第二次:

  • /"([^"]*)"/處理您的示例輸入。
  • 當處理的HTML字符串,建議使用HTML解析器:的DomDocument等

*重要的是,我的模式是隻用來處理$end爲單個字符。如果它不止一個字符,那麼該模式將無法按預期工作,需要修改。

這是一個稍慢圖案/ preg_match()呼叫,這將允許更大$end串:(Pattern Demo

preg_match_all('/'.preg_quote($start,'/').'\K.*?(?='.preg_quote($end,'/').')/',$content,$out)?$out[0]:''; 
+0

非常感謝您的回答 – user1708580

+1

歡迎您。我很樂意爲您解釋提供一個強大而優化的答案。它將在未來幫助其他人。 – mickmackusa

相關問題