本文介绍了正则表达式单行多匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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内容封装使用的是负字符集,而不是简单的.+.*,因为它们在默认情况下是贪婪的;可以分别使用.+?.*?来更改这一点,但是负字符集会减少回溯。

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

这篇关于正则表达式单行多匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-29 13:10