php regex extract匹配tag包含特定单词的位置

时间:2022-09-13 16:45:08

I have the following string:

我有以下字符串:

<product><name>Tea</name><price>12</price></product>
<product><name>black coffee</name><price>23</price></product>
<product><name>cheap black-coffee</name><price>44</price></product>

I would like to grab all products where "coffee" or "coffee black" occurs.

我想抓住所有出现“咖啡”或“咖啡黑”的产品。

I tried with the following code:

我尝试使用以下代码:

preg_match_all('/<product>(.*?)(black coffee|black-coffee)(.*?)<\/product>/is', $string, $result);

But that code merges two of the products in the array. As you can tell, I am not at all familiar with regex.

但该代码合并了阵列中的两个产品。你可以说,我对正则表达式并不熟悉。

1 个解决方案

#1


You need to use a negative lookahead assertion instead of .*? because .*? will also match <product> or </product> tags.

你需要使用负前瞻断言而不是。*?因为。*?还将匹配 或 标签。

<product>((?:(?!<\/?product).)*?)(black coffee|black-coffee)((?:(?!<\/?product).)*?)<\/product>

DEMO

$re = "/<product>(?:(?:(?!<\\/?product).)*?)(?:black coffee|black-coffee)(?:(?:(?!<\\/?product).)*?)<\\/product>/is";
$str = "<product><name>Tea</name><price>12</price></product>\n<product><name>black coffee</name><price>23</price></product>\n<product><name>cheap black-coffee</name><price>44</price></product>";
preg_match_all($re, $str, $matches);
print_r($matches[0])

#1


You need to use a negative lookahead assertion instead of .*? because .*? will also match <product> or </product> tags.

你需要使用负前瞻断言而不是。*?因为。*?还将匹配 或 标签。

<product>((?:(?!<\/?product).)*?)(black coffee|black-coffee)((?:(?!<\/?product).)*?)<\/product>

DEMO

$re = "/<product>(?:(?:(?!<\\/?product).)*?)(?:black coffee|black-coffee)(?:(?:(?!<\\/?product).)*?)<\\/product>/is";
$str = "<product><name>Tea</name><price>12</price></product>\n<product><name>black coffee</name><price>23</price></product>\n<product><name>cheap black-coffee</name><price>44</price></product>";
preg_match_all($re, $str, $matches);
print_r($matches[0])