正则表达式取代reg商标

时间:2009-09-02 14:35:03

标签: php html regex preg-replace symbols

我需要一些正则表达式的帮助:

我有一个html输出,我需要用<sup></sup>

包装所有注册商标

我无法在title和<sup>属性中插入alt标记,显然我不需要包含已经上标的reg。

以下正则表达式匹配不属于HTML标记的文本:

(?<=^|>)[^><]+?(?=<|$)

我正在寻找的一个例子:

$original = `<div>asd&reg; asdasd. asd<sup>&reg;</sup>asd <img alt="qwe&reg;qwe" /></div>`

过滤后的字符串应输出:

<div>asd<sup>&reg;</sup> asdasd. asd<sup>&reg;</sup>asd <img alt="qwe&reg;qwe" /></div>

非常感谢您的时间!!!

4 个答案:

答案 0 :(得分:3)

我真的会使用HTML解析器来代替正则表达式,因为HTML不是常规的,并且会出现比您梦想的更多边缘情况(忽略您在上面已经确定的上下文限制)。

您没有说出您正在使用的技术。如果你发布,有人可以毫无疑问地推荐合适的解析器。

答案 1 :(得分:3)

嗯,如果您同意遵守限制,这是一种简单的方法:

那些已经处理的注册表具有&lt; / sup&gt;紧跟在&amp; reg;

之后
echo preg_replace('#&reg;(?!\s*</sup>|[^<]*>)#','<sup>&reg;</sup>', $s);

背后的逻辑是:

  1. 我们只替换那些&amp; reg;其后没有&lt; / sup&gt;和...
  2. 未跟随&gt; simbol没有打开&lt;符号

答案 2 :(得分:0)

正则表达不足以满足您的需求。首先,您必须编写代码以确定内容何时是元素的值或元素的文本节点。然后你必须通过所有内容并使用一些替换方法。我不确定它在PHP中是什么,但在JavaScript中它看起来像:

content[i].replace(/\&reg;/g, "<sup>&reg;</sup>");

答案 3 :(得分:0)

我同意Brian的观点,正则表达式不是解析HTML的好方法,但如果你必须使用正则表达式,你可以尝试将字符串拆分为标记,然后在每个标记上运行正则表达式。

我正在使用preg_split将字符串拆分为HTML标记以及短语<sup>&reg</sup> - 这将使文本不是已经上标&reg;或者标记为标记。然后,对于每个令牌,&reg;可以替换为<sup>&reg;</sup>

$regex = '/(<sup>&reg;<\/sup>|<.*?>)/i';
$original = '<div>asd&reg; asdasd. asd<sup>&reg;</sup>asd <img alt="qwe&reg;qwe" /></div>';

// we need to capture the tags so that the string can be rebuilt
$tokens = preg_split($regex, $original, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
/* $tokens => Array
(
    [0] => <div>
    [1] => asd&reg; asdasd. asd
    [2] => <sup>&reg;</sup>
    [3] => asd
    [4] => <img alt="qwe&reg;qwe" />
    [5] => </div>
)
*/

foreach ($tokens as &$token)
{
    if ($token[0] == "<") continue; // Skip tokens that are tags
    $token = substr_replace('&reg;', '<sup>&reg;</sup>');
}

$tokens = join("", $tokens); // reassemble the string
// $tokens => "<div>asd<sup>&reg;</sup> asdasd. asd<sup>&reg;</sup>asd <img alt="qwe&reg;qwe" /></div>"

请注意,这是一种天真的方法,如果输出未按预期格式化,则可能无法像您希望的那样解析(再次,正则表达式不适合HTML解析;)