在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>';
任何帮助表示感谢。
答案 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