2017-08-30 42 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

相关问题