我错过了一些让我无法使用递归(?R)的事情。
解释我的问题的一个例子'明确':
$str1 = "somes text -start bla bla FIND bla bla bla FIND bla FIND bla end-";
$str2 = "somes text -start bla bla FIND bla bla bla FIND bla FIND bla end-";
$my_pattern = "-start .*(FIND).* end-";
preg_replace_callback($my_pattern, 'callback', $str1.$str2);
它只匹配最后一个FIND。
' ungreedy'选项i匹配$ str的第一个FIND。
但我怎样才能得到所有这些?我试图使用'(?R)'但我真的不明白它是如何运作的。
感谢。
编辑:真正的工作是找到所有的标题&#39;财产<a>
&amp; </a>
。
我知道使用正则表达式解析html并不是优化,但它只是学校中的一项工作来学习正则表达式。
这就是为什么我没有把真正的工作,我想了解并能够自己做。
<html>
<head><title>Nice page</title></head>
<body>
Hello World
<a href=http://cyan.com title="a link">
this is a link
</a>
<br />
<a href=http://www.riven.com> Here too <img src=wrong.image title="and again">
<span>Even that<div title="same">all the same</div></span>
</a>
</body>
</html>
我的工作也是使用正则表达式将每个标题都用大写(标题=&#34; A LINK&#34;例如)。
我的最后一个模式是:
#<a .* title=\"(.*)\".*</a>#Uis
让我抓住(标题=&#34;链接&#34;)和(标题=&#34;再次&#34;)。你的方法应该工作(stribizhev),但我没有成功实现它,我还在它上面。
答案 0 :(得分:1)
您需要将DOMDocument与DOMXPath一起使用,以安全地获取所有标题属性并使用mb_strtoupper
更改它们:
$html = "<<YOUR_HTML>>";
$dom = new DOMDocument('1.0', 'UTF-8');
$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($dom);
$titles = $xpath->query('//a[@title]');
foreach($titles as $title) {
$title->setAttribute("title", mb_strtoupper($title->getAttribute("title"), 'UTF-8'));
}
echo $dom->saveHTML();
请参阅IDEONE demo。
//a[@title]
xpath获取<a>
元素(a
),其属性为title
。
假设您有UTF8输入,我使用mb_strtoupper
。请相应调整,或者如果您不打算使用Unicode,只需使用strtoupper
。
以下是一个正则表达式,可让您替换FIND
和-start
中的所有-end
子字符串:
(-start|(?!^)\G)(.*?)FIND(?=.*end-)
请参阅demo
替换为$1$2NEW_WORD
。
$re = "#(-start|(?!^)\G)(.*?)FIND(?=.*end-)#";
$str = "somes text -start bla bla FIND bla bla bla FIND bla FIND bla end-";
$subst = "$1$2NEW_WORD";
$result = preg_replace($re, $subst, $str);
echo $result;
注意:如果您有多个start-end
块,则很可能需要一个驯化的贪婪令牌(?:(?!-start|end-|FIND).)*
而不是.*?
和.*
正则表达式分解:
(-start|(?!^)\G)
- 此组包含两个选项:
-start
- 匹配文字字符串-start
(?!^)\G
- 在最后一次成功匹配后立即断言原始输入字符串中的位置。 \G
也可以断言字符串的开头,但我们会将其排除在负面预测之外。(.*?)
- 匹配任意数量的字符,但尽可能少FIND
- 文字字符串FIND
(?=.*end-)
- 仅在end-
后面有文字字符串FIND
。有关\G
运算符的详细信息,请参阅When is \G useful application in a regex?和What good is \G in a regular expression?。
答案 1 :(得分:0)
如果使用preg_replace_callback
,为什么reluctant .*?
不方便。
$my_pattern = "/-start(.*?)end-/s";
$str = preg_replace_callback($my_pattern, function($matches) {
return str_replace("FIND", "<b>FIND</b>", $matches[0]);
}, $str1.$str2);
或者在回调中做其他事情。你想要实现什么目标?