【问题标题】:I need to quickly remove a set of classes from an arbitrary string of html我需要从任意 html 字符串中快速删除一组类
【发布时间】:2015-10-07 03:36:08
【问题描述】:

HTML 首先通过净化器(tinyMCE+Wordpress)运行,因此它应该匹配一些标准格式。所有脚本和样式标签都被剥离,标签内的所有数据都是html_encoded,所以不用担心多余的符号。

我知道用正则表达式解析 html 的一般立场是“不要”,但在这个具体的例子中,问题似乎不像是解析,而更像是简单的字符串处理......我是否错过了一些看不见的水平复杂性?

据我所知,似乎有问题的模式可以分解为逻辑组件:

  1. /<[a-zA-Z][^>]+ - 匹配任何 html 标记的开头以及其中的任何标记和属性组合,但不匹配结束括号
  2. (?i:class)=\" - 类属性的开头,不区分大小写
  3. (?: - 启动非捕获子模式
  4. (?: *[a-zA-Z_][\w-]* +)* - 任意数量的类名(或无),但如果存在,则捕获前必须有空格
  5. ( *.implode('|', $classes).*) - 要捕获的类集,preg_quoted
  6. (?: +[a-zA-Z_][\w-]* *)* - 任意数量的类名(或无),但如果存在,则捕获后必须有空格
  7. )+ - 关闭非捕获子模式并循环它,以防多个匹配类在一个属性中
  8. \"(?: [^>]*)>/ - class 属性的结尾,以及 html 标记结尾的所有内容

制作最终的正则表达式:

$pattern = "/<[a-zA-Z][^>]+ (?i:class)=\"(?:(?: *[a-zA-Z_][\w-]* +)*( *".implode('|', $classes)." *)(?: +[a-zA-Z_][\w-]* *)*)+\"(?: [^>]*)>/";

我还没有尝试运行它,因为我知道它是否有效,我会很想使用它,但是通过 preg_replace 运行它似乎应该可以完成这项工作,除了一个小问题.我相信它会在捕获区域周围留下多余的空白。这不是什么大问题,但如果有人知道怎么做,最好避免。

还应注意,这不是关键任务过程,如果我的捕获偶尔无法删除类,则没有人死亡。

所以,本质上...有人能解释一下在这种情况下是什么让这成为一个坏主意吗?

【问题讨论】:

  • 复杂性在于:class 属性的开头只能与\bclass 匹配,类名可以包含很多东西——但也许你知道你在做什么, preg_quote 如果边界处有单词字符,则有效,否则?如果 &gt; 没有实体化 (class="dd&gt;") 怎么办?
  • @stribizhev - 类名中的 &gt; 之类的边缘情况将被清理程序过滤并删除,然后再获取此代码,并且非常期望收到的代码将被由逻辑脚本生成,引导。但是,我不确定我是否关注类属性的问题......详细说明? @Robert - 我担心速度。这种修改需要在每次页面加载时运行(我知道,但我在很多方面都受到限制),并且将 html 解析为 DOM 对象比正则表达式引擎占用更多的内存/cpu。

标签: php html regex


【解决方案1】:

好的,这是您要从给定 html 中删除的类名列表吗?

我的意思是,您要删除的给定类名列表是什么。你能举一个典型的html的例子,它是什么,你想把它改成什么。 示例:

之前

<div class="someClass">
  <i class="dontchange doChange"></i>
  <a class="hello john"></a>
</div>

改成

<div>
  <i class="dontchange"></i>
  <a></a>
</div>

【讨论】:

  • 我打算根据具体情况填充类名列表,但它们将是一组已转义以在正则表达式中使用的字符串文字。要删除的类名在功能上等同于 (str1|str2|str3)。您的示例是准确的,尽管我不需要删除空类属性...在最坏的情况下,事后我可以用 str_replace 清理它们
【解决方案2】:

这将替换所有 html 中的所有类。

myHtml.replace(/class\=\"[^\"]*\"/g,'');

这就是你要找的吗?或者更具体的?

【讨论】:

  • 或者如果有一个非常不寻常的边缘情况,其中 class="" 在标签中不存在,您可以这样做:myHtml.replace(/(]*)class\=\ "[^\"]*\"/g,'$1');
  • 不,尝试仅替换出现在给定列表中的类,而不是匹配所有类
  • 给定的列表是什么?
  • 它将是一个 preg_escaped 字符串列表,可能会因使用而异...在任何正则表达式中,它们在功能上应该等同于 (str1|str2|str3)
猜你喜欢
  • 1970-01-01
  • 2015-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-24
  • 2013-03-04
相关资源
最近更新 更多