我想在两个子串之间提取子串。问题是它只会提取第一个。我想在我的所有文件中都这样做。
示例:
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;
现在它只提取777777
AAAAA
。但我想要的是777777
AAAAAA
888888
BBBBBB
999999
CCCCC
答案 0 :(得分: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
在模式中使用了两次 - 一次在“否定字符类”[^"]
中,第二次在“正向前瞻”中(?=")
仅供记录:
/"([^"]*)"/
将处理您的示例输入。 *重要的是,我的模式仅用于处理$end
作为单个字符。如果它不止一个字符,那么该模式将无法按预期工作,需要进行修改。
这是一个稍慢的模式/ preg_match()
调用,允许更大的$end
字符串:(Pattern Demo)
preg_match_all('/'.preg_quote($start,'/').'\K.*?(?='.preg_quote($end,'/').')/',$content,$out)?$out[0]:'';
答案 1 :(得分: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 :(得分:0)
我担心您的样本输入与您的实际输入很差,因此很难猜测您实际需要的准确性水平。
我将放弃不依赖正则表达式手术的高度稳定的技术。请注意,data-
属性在有效的html文档中应该全部小写。
代码:(Demo)
function getValue($html, $tag, $attr) {
$dom = new DOMDocument;
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$result = [];
foreach ($xpath->query("//{$tag}[@{$attr}]") as $node) {
$result[] = $node->getAttribute($attr);
}
return implode(',', $result);
}
$html = '<a data-id="777777"></a><a data-id="888888"></a><a data-id="99999"></a>';
$tag = 'a';
$attr = 'data-id';
echo getValue($html, $tag, $attr);
echo "\n---\n";
$html = '<a data-A="AAAAAA"></a><a data-A="BBBBBB"></a><a data-A="CCCCCC"></a>';
$tag = 'a';
$attr = 'data-a';
echo getValue($html, $tag, $attr);
输出:
777777,888888,99999
---
AAAAAA,BBBBBB,CCCCCC