2

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

我得到了一个 html 输出,我需要用<sup></sup>

我不能<sup>在标题和alt属性中插入标签,显然我不需要包装已经上标的 regs。

以下正则表达式匹配不属于 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

4 回答 4

3

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

你没有说你正在使用什么技术。如果你把它贴出来,毫无疑问有人会推荐合适的解析器。

于 2009-09-02T14:39:21.477 回答
3

好吧,如果您同意以下限制,这是一个简单的方法:

那些已经被处理过的regs在®之后有</sup>。

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

背后的逻辑是:

  1. 我们只替换那些 ® 后面没有 </sup> 和...
  2. 后面没有 > simbol 没有打开 < 符号
于 2009-09-02T16:41:10.760 回答
0

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

content[i].replace(/\&reg;/g, "<sup>&reg;</sup>");
于 2009-09-02T15:31:56.143 回答
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 解析;))

于 2009-09-02T16:06:30.283 回答