我正在寻找一个正则表达式(php)来查找/替换网页中的某些单词。但是,它不能替换所有html标签之间的单词,只能在:italic< i >,粗体< b >之间。和纯文本。
示例:
字:“你好”(不区分大小写)
<a href="#">Hello</a> im a writer that i like to say hello everyday. <b>Hello</b> Spiderman.
替换:在锚点不能替换时,只能替换你好和< b>Hello< /b>
。
我测试了一些正则表达式但没有一个正常工作:
1)来自SMART SEO LINKS(WP插件)
$reg = '/(?!(?:[^<\[]+[>\]]|[^>\]]+<\/a>))\b($word)\b/Imsu';
效果不好,有时删除内容并将simbol“&gt;” 我对这个正则表达式进行了一些修改,删除了“?!”或“?:”(我不知道什么意思),但停止工作。
2)其他人我一直在尝试:
$reg = "/<([\w]+)[^>]*>\b('.$word.')\b<\/\1>/Imsu";
$reg = '/<+\s*\/\s\b('.$word.')\b[^>]\/\s>+/I';
不能替换任何东西
$reg = '/<(\w+)[^>]*>\b('.$name.')\b<\/\1>/Imsu';
有时会奏效。
事实是,我不是正则表达式专家,而且我几天都在测试,尝试创建一个新的正则表达式,但不能满足我需要的结果。
事实是,替换将用于WP插件,有时会影响模板或其他插件或DOM没有很好地创建
任何人都知道为什么不能正常工作?感谢。
答案 0 :(得分:2)
尝试组合这些模式
$reg = '/(?:<(\w+)[^>]*>)?\bhello\b(?!<\/a>)(<\/\\1>)?/i';
$reg0 = '/<\w[^>]*\bhello\b[^>]*>/Ui';
示例强>
$word = preg_quote('hello','/'); // to avoid PCRE injection
$str = '<a href="hello.php">Hello</a> I say hello everyday. <b>Hello</b> Spiderman.';
$reg = '/(?:<(\w+)[^>]*>)?\b'.$word.'\b(?!<\/a>)(<\/\\1>)?/i';
$reg0 = '/<\w[^>]*\b'.$word.'\b[^>]*>/Ui';
function handler($m) { return str_replace($GLOBALS["word"],'!X!',$m[0]); }
$str = preg_replace_callback($reg0,'handler',$str); // replace "hello" for say !X! inside tags
$str = preg_replace($reg,'[deleted]',$str); // delete "hello" elsewhere
$str = str_replace('!X!',$word,$str); // put "hello" inside tag back
print_r($str);
<强>结果强>
<a href="hello.php">Hello</a> I say [deleted] everyday. [deleted] Spiderman.
您的问题备注
<强>解释强>
请参阅上面关于断言的链接:?<!
用于负向后看断言不能用于匹配<a href="#">
,因为它不是固定长度并导致编译错误。因此,我在hello之后使用lookahead断言?!
来匹配</a>
。开头和结尾的括号包括任何周围的HTML标记,因此除了</a>
断言之外的所有内容都将被替换。
避免在标签内部替换 hello 的技巧是将它们替换为一些唯一的字符串(比如!X!
),然后进行原始替换,然后替换!X!
你好回来。它可能不是最好的解决方案,但它确实有效。
为什么你的正则表达式不起作用
您使用了/I
修饰符(位于模式的末尾)。修饰符区分大小写,/i
表示不区分大小写的评估,请参阅the list of modifiers。我相信你的模式中的\b
(字边界)是多余的。