Php 如果元素旁边存在文本,则获取元素内容
我在Php 如果元素旁边存在文本,则获取元素内容,php,regex,Php,Regex,我在$string中有这个HTML: $string = '<p>random</p> <a href="">Test 1</a> (target1) <br> <a href="">Test 2</a> (target1) <br> <a href="">Test 3</a> (skip) // etc '; 如何搜索$string以查找$array中的所有术语,并获取其
$string
中有这个HTML:
$string = '<p>random</p>
<a href="">Test 1</a> (target1)
<br>
<a href="">Test 2</a> (target1)
<br>
<a href="">Test 3</a> (skip)
// etc
';
如何搜索$string
以查找$array
中的所有术语,并获取其前面的
标记的内容
因此,我得出以下结果:
$results = array(
array(
'text' => 'Test 1',
'needle' => 'target1'
),
array(
'text' => 'Test 2',
'needle' => 'target1'
)
);
我将使用javascript给您一个答案,但php也可以做同样的事情 您可以一次搜索数组中的1个字符串,并在未找到任何结果且到达数组末尾时完成搜索
target1Match = s.match(/<.+?>(.+?)<\/.+?> *\(target1\)/);
// target1Match is now [<a href="">Test 1</a> (target1), Test 1]
target1Match = target1Match[1];
target2Match = s.match(/<.+?>(.+?)<\/.+?> *\(target2\)/);
// target1Match is now [<a href="">Test 2</a> (target2), Test 2]
target2Match = target2Match[1];
target1Match=s.match(/(.+?)*\(target1\)/);
//target1Match现在是[(target1),测试1]
target1Match=target1Match[1];
target2Match=s.match(/(.+?)*\(target2\)/);
//目标1匹配现在是[(目标2),测试2]
target2Match=target2Match[1];
使用“target1和2”的变量构建正则表达式
匹配多个目标和特定标签
s.match(/<a.+?>(.+?)<\/a> *\((target1|target2)\)/);
s.match(/(.+?)*\((target1 | target2)\)/);
使用:
//假设HTML为$str,术语为$terms
$results=[];
foreach(条款为$t){
//获取的内容我是JayBlanchard阵营的成员。下面是一个解决方案,它正确地使用了DomDocument和Xpath,并通过动态生成的查询将目标设置为)
我们总是很乐意帮助和支持新的程序员,但您需要先帮助自己。:-)如果您有问题,请发布您尝试过的内容,并清楚地解释哪些内容不起作用,然后提供。阅读一个好问题。一定要阅读。使用有趣的语句。我可以添加一个“或”语句吗,这样正则表达式就在一行中。类似:/(.+?)*\(target1 | target2\)/
等。此外,我是否可以调整正则表达式,使其只针对您可以使用或,但随后您需要添加一个新的捕获组,以便您知道哪个目标匹配。您可以匹配如下特定标记:s.match(/(.+?)*((target1 | target2))/);为什么要使用正则表达式和DOM解析器?为什么要使用正则表达式和DOM解析器?@JayBlanchard OP记录了您的评论并发表了文章。我不知道如何使用DOM解析器,但我与正则表达式共享一个解决方案。我并不是说这更好。@JayBlanchard请随意演示如何使用DOM进行操作。我无法实现它这就是我为什么选择regex路线的原因。
s.match(/<a.+?>(.+?)<\/a> *\((target1|target2)\)/);
// Assuming your HTML as $str, your terms as $terms
$results = [];
foreach ($terms as $t) {
// Get content of <a> tag preceeding the term
preg_match_all('/<a ?.*>(.*)<\/a>\s+' . preg_quote($t) . '/', $str, $matches);
//Then insert into your result array
foreach ($matches[1] as $m) {
$results[] = [
'text' => $m,
'needle' => $t
];
}
}
// echo '<pre>' . print_r($results, true) . '</pre>';
Array
(
[0] => Array
(
[text] => Test 1
[needle] => (target1)
)
[1] => Array
(
[text] => Test 2
[needle] => (target1)
)
)
//a[following-sibling::text()[1][contains(.,'(target1)') or contains(.,'(target2)')]]
$html = '<p>random</p>
<a href="">Test 1</a> (skip)
<br>
<a href="">Test 2</a> (target1)
<br>
<a href="">Test 3</a> (target1)
<br>
<a href="">Test 4</a> (skip)
<br>
<a href="">Test 5</a> (target2)
<br>
<a href="">Test 6</a> (skip)
';
$needles = [
'(target1)',
'(target2)'
];
$contains = array_reduce($needles, function($carry, $needle) {
return $carry .= ($carry !== null ? ' or ' : '') . "contains(.,'$needle')";
});
$matches = [];
$dom=new DOMDocument;
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
foreach ($xpath->query("//a[following-sibling::text()[1][$contains]]") as $node) {
$matches[] = ["text" => $node->nodeValue, "needle" => trim($node->nextSibling->nodeValue)];
}
var_export($matches);
array (
0 =>
array (
'text' => 'Test 2',
'needle' => '(target1)',
),
1 =>
array (
'text' => 'Test 3',
'needle' => '(target1)',
),
2 =>
array (
'text' => 'Test 5',
'needle' => '(target2)',
),
)