【问题标题】:regular expression to strip attributes and values from html tags正则表达式从 html 标签中去除属性和值
【发布时间】:2008-11-12 21:36:50
【问题描述】:

大家好,我是正则表达式的新手,你能帮我解决这个问题吗?

我有一个像 "<input attribute='value' >" 这样的字符串,其中 attribute='value' 可以是任何东西,我想得到一个 preg_replace 来得到 <input />

如何指定通配符来替换 srting 中任意数量的任意字符?

喜欢这样吗? preg_replace("/<input.*>/",$replacement,$string);

非常感谢

【问题讨论】:

    标签: php regex preg-replace


    【解决方案1】:

    你有什么:

    .*
    

    将匹配“任何字符,并且尽可能多。

    你的意思是

    [^>]+
    

    翻译为“任何字符,那不是“>”,并且必须至少有一个

    或者,

    .*?
    

    这意味着 “任何字符,但仅足以使此规则生效”

    但不要

    用正则表达式解析 HTML 不好

    使用任何现有的 html 解析器,DOM 库,任何东西,只是不是 NAïVE REGEX

    例如:

     <foo attr=">"> 
    

    会被正则表达式错误地抓取为

    '<foo attr=" ' with following text of '">' 
    

    这将引导你到这个正则表达式:

     `<[a-zA-Z]+( [a-zA-Z]+=['"][^"']['"])*)>  etc etc 
    

    这时你会发现这颗可爱的宝石:

     <foo attr="'>\'\"">
    

    你的头会爆炸。

    (语法高亮验证了我的观点,并且错误地匹配了我已经结束标记的想法。)

    【讨论】:

    • 在大多数文档中,“尽可能多”与“刚刚好”的概念被称为“贪婪”。
    • @John:是的,我知道,但这家伙显然是绿色的;)
    • 你在头部爆炸部分是对的......从经验中说。
    • 您如何认为像“”这样的怪物在 HTML 中甚至是可能的?我知道你谈论 XSS,但我想我们不是在看“如何清理损坏的用户输入?”问题在这里。允许用户输入 HTML 本身就是一个很大的 WTF。
    【解决方案2】:

    有些人很接近...但不是 100%:

    这个:

    preg_replace("<input[^>]*>", $replacement, $string);
    

    应该是这样的:

    preg_replace("<input[^>]*?>", $replacement, $string);
    

    你不希望这是一场贪婪的比赛。

    【讨论】:

    • 贪婪在这里无关紧要,因为使用 [^>]* 而不是 .* 将导致它匹配所有非>字符,直到找到 > 并且最长(贪婪)和最短( non-greedy) 非-> 字符后跟 > 的运行在所有情况下都是相同的。
    【解决方案3】:
    preg_replace("<input[^>]*>", $replacement, $string); 
    // [^>] means "any character except the greater than symbol / right tag bracket"
    

    这真的是基本的东西,你应该catch up with some reading。 :-)

    【讨论】:

    • 这几乎可以工作,但它在值中包含“>”的属性上失败,例如.
    • @Adam:这正是为什么你不应该使用 Regex 来解析 html。
    • 有趣的是,在属性值中允许 > 似乎只是为了表明反对在 HTML 上使用正则表达式(我从未见过它在现实生活中使用过)。但这是一个很好的观点。
    • @PHiLho,希望不会在现实生活中使用,但它是人们为 XSS 目的创建代码的方式之一。而且很快就会变得丑陋。
    • 很抱歉,属性值中没有“>”字符。绝不。如果 您的 HTML 中有,那么您将面临一个完全不同的问题。
    【解决方案4】:

    如果我正确理解了这个问题,你有代码:

    preg_replace("/<input.*>/",$replacement,$string);
    

    您希望我们告诉您应该使用 $replacement 来删除与 .* 匹配的内容

    你必须反其道而行之。使用捕获组来捕获您想要保留的内容,并将其重新插入替换中。例如:

    preg_replace("/(<input).*(>)/","$1$2",$string);
    

    当然,您实际上并不需要在这里捕获组,因为您只是重新插入文字文本。打赌上面显示了该技术,以防您想在标签可能变化的情况下执行此操作。这是一个更好的解决方案:

    preg_replace("/<input [^>]*>/","<input />",$string);
    

    否定字符类比点更具体。如果字符串中有两个 HTML 标记,则此正则表达式将起作用。你原来的正则表达式不会。

    【讨论】:

      猜你喜欢
      • 2011-05-03
      • 2013-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-01
      • 2011-05-15
      • 1970-01-01
      • 2023-03-10
      相关资源
      最近更新 更多