正则表达式单行多匹配

2022-03-23 00:00:00 regex php preg-replace

在PHP中使用preg_replace时,我尝试在一个字符串中多次匹配一个正则表达式模式,有时1行有2个匹配,有时不匹配。

我有以下字符串:

 $text = 'Check <a href="link1">text1</a> or <a href="link2">text2</a>
 oh
 well <a href="link3">text3</a>';

我希望将其转换为:

 Check
 text1
 link1
 or
 text2
 link2
 oh
 well
 text3
 link3

我有这个:

 $text = preg_replace('/(<a href=")(.+)(">)(.*)(</a>)/', "
$4
$2
", $text);

但它不起作用,只有在一行有1个匹配的情况下。点赞:

 $text = 'Check <a href="link1">text1</a> 
 or <a href="link2">text2</a>
 oh
 well <a href="link3">text3</a>'; 

感谢任何帮助。

使用a和b的示例 http://www.phpliveregex.com/p/4fU

HTML

迭代在给定推荐答案中可以找到的所有文本节点,并为父锚点创建特殊情况:

$text = 'Check <a href="link1">text1</a> or <a href="link2">text2</a>
 oh
 well <a href="link3">text3</a>';

$dom = new DOMDocument;
$dom->loadHTML($text);

$xpath = new DOMXPath($dom);

foreach ($xpath->query('//text()') as $node) {
  if ($node->nodeType == XML_TEXT_NODE) {
        echo $node->textContent, "
";
        if ($node->parentNode->nodeType == XML_ELEMENT_NODE && $node->parentNode->nodeName == 'a') {
                echo $node->parentNode->getAttribute('href'), "
";
        }
  }
}

在文本域中,您可以这样做:

echo preg_replace('~<a href="([^"]+)">([^<]+)</a>~i', "
$2
$1", $text);

基本上,href和tag内容封装使用的是负字符集,而不是简单的.+.*,因为它们在默认情况下是贪婪的;可以分别使用.+?.*?来更改这一点,但是负字符集会减少回溯。

另外,您只需要对锚点的两个部分执行内存捕获,而不是对全部五个部分执行内存捕获。

相关文章