【发布时间】:2015-10-07 03:36:08
【问题描述】:
HTML 首先通过净化器(tinyMCE+Wordpress)运行,因此它应该匹配一些标准格式。所有脚本和样式标签都被剥离,标签内的所有数据都是html_encoded,所以不用担心多余的符号。
我知道用正则表达式解析 html 的一般立场是“不要”,但在这个具体的例子中,问题似乎不像是解析,而更像是简单的字符串处理......我是否错过了一些看不见的水平复杂性?
据我所知,似乎有问题的模式可以分解为逻辑组件:
-
/<[a-zA-Z][^>]+- 匹配任何 html 标记的开头以及其中的任何标记和属性组合,但不匹配结束括号 -
(?i:class)=\"- 类属性的开头,不区分大小写 -
(?:- 启动非捕获子模式 -
(?: *[a-zA-Z_][\w-]* +)*- 任意数量的类名(或无),但如果存在,则捕获前必须有空格 -
( *.implode('|', $classes).*)- 要捕获的类集,preg_quoted -
(?: +[a-zA-Z_][\w-]* *)*- 任意数量的类名(或无),但如果存在,则捕获后必须有空格 -
)+- 关闭非捕获子模式并循环它,以防多个匹配类在一个属性中 -
\"(?: [^>]*)>/- class 属性的结尾,以及 html 标记结尾的所有内容
制作最终的正则表达式:
$pattern = "/<[a-zA-Z][^>]+ (?i:class)=\"(?:(?: *[a-zA-Z_][\w-]* +)*( *".implode('|', $classes)." *)(?: +[a-zA-Z_][\w-]* *)*)+\"(?: [^>]*)>/";
我还没有尝试运行它,因为我知道它是否有效,我会很想使用它,但是通过 preg_replace 运行它似乎应该可以完成这项工作,除了一个小问题.我相信它会在捕获区域周围留下多余的空白。这不是什么大问题,但如果有人知道怎么做,最好避免。
还应注意,这不是关键任务过程,如果我的捕获偶尔无法删除类,则没有人死亡。
所以,本质上...有人能解释一下在这种情况下是什么让这成为一个坏主意吗?
【问题讨论】:
-
复杂性在于:
class属性的开头只能与\bclass匹配,类名可以包含很多东西——但也许你知道你在做什么,preg_quote如果边界处有单词字符,则有效,否则?如果>没有实体化 (class="dd>") 怎么办? -
@stribizhev - 类名中的
>之类的边缘情况将被清理程序过滤并删除,然后再获取此代码,并且非常期望收到的代码将被由逻辑脚本生成,引导。但是,我不确定我是否关注类属性的问题......详细说明? @Robert - 我担心速度。这种修改需要在每次页面加载时运行(我知道,但我在很多方面都受到限制),并且将 html 解析为 DOM 对象比正则表达式引擎占用更多的内存/cpu。