Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如果元素旁边存在文本,则获取元素内容_Php_Regex - Fatal编程技术网

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)',
  ),
)