正则表达式单行多重匹配

时间:2014-03-17 13:21:12

标签: php regex 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>)/', "\n$4\n$2\n", $text);

但它不起作用,只有在一条线上有一场比赛时才有效。像:

 $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

2 个答案:

答案 0 :(得分:1)

迭代您可以在给定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, "\n";
        if ($node->parentNode->nodeType == XML_ELEMENT_NODE && $node->parentNode->nodeName == 'a') {
                echo $node->parentNode->getAttribute('href'), "\n";
        }
  }
}

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

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

基本上,您为href和标记内容框使用负字符集,而不仅仅是.+.*,因为默认情况下它们是贪婪的;这可以分别使用.+?.*?进行更改,但负字符集可以减少回溯。

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

答案 1 :(得分:-2)

不是您的问题,但您可以在最后一次斜杠后添加修饰符到正则表达式模式:

preg_replace('/ whatever_my_pattern_do / MODIFIERS',“这里我替换”,$ text);

您应该检查所有here