正则表达式替换网页中的单词

时间:2013-05-07 10:50:59

标签: php regex wordpress html-parsing preg-replace

我正在寻找一个正则表达式(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没有很好地创建

任何人都知道为什么不能正常工作?感谢。

1 个答案:

答案 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(字边界)是多余的。