正则表达式拆分HTML标签

时间:2010-10-28 16:19:13

标签: regex

我有一个像这样的HTML字符串:

<img src="http://foo"><img src="http://bar">

将此分割为两个独立的img标记的正则表达式模式是什么?

5 个答案:

答案 0 :(得分:7)

你对你的字符串完全有多确定?这样输入怎么样:

<img alt=">"          src="http://foo"  >
<img src='http://bar' alt='<'           >

这是什么编程语言?您是否有一些理由不使用标准的HTML解析类来处理这个问题?当您拥有一组非常着名的输入时,正则表达式只是一种很好的方法。它们不适用于真正的HTML,仅适用于操纵演示。

即使你必须使用正则表达式,你也应该使用正确的语法。这很容易。我已在万亿网页上测试了以下程序。它处理了我上面概述的案例 - 以及其他一两个案例。

#!/usr/bin/perl
use 5.10.0;
use strict;
use warnings;

my $img_rx = qr{

    # save capture in $+{TAG} variable
    (?<TAG> (?&image_tag) )

    # remainder is pure declaration
    (?(DEFINE)

        (?<image_tag>
            (?&start_tag)
            (?&might_white) 
            (?&attributes) 
            (?&might_white) 
            (?&end_tag)
        )

        (?<attributes>
            (?: 
                (?&might_white) 
                (?&one_attribute) 
            ) *
        )

        (?<one_attribute>
            \b
            (?&legal_attribute)
            (?&might_white) = (?&might_white) 
            (?:
                (?&quoted_value)
              | (?&unquoted_value)
            )
        )

        (?<legal_attribute> 
            (?: (?&required_attribute)
              | (?&optional_attribute)
              | (?&standard_attribute)
              | (?&event_attribute)
              # for LEGAL parse only, comment out next line 
              | (?&illegal_attribute)
            )
        )

        (?<illegal_attribute> \b \w+ \b )

        (?<required_attribute>
            alt
          | src
        )

        (?<optional_attribute>
            (?&permitted_attribute)
          | (?&deprecated_attribute)
        )

        # NB: The white space in string literals 
        #     below DOES NOT COUNT!   It's just 
        #     there for legibility.

        (?<permitted_attribute>
            height
          | is map
          | long desc
          | use map
          | width
        )

        (?<deprecated_attribute>
             align
           | border
           | hspace
           | vspace
        )

        (?<standard_attribute>
            class
          | dir
          | id
          | style
          | title
          | xml:lang
        )

        (?<event_attribute>
            on abort
          | on click
          | on dbl click
          | on mouse down
          | on mouse out
          | on key down
          | on key press
          | on key up
        )

        (?<unquoted_value> 
            (?&unwhite_chunk) 
        )

        (?<quoted_value>
            (?<quote>   ["']      )
            (?: (?! \k<quote> ) . ) *
            \k<quote> 
        )

        (?<unwhite_chunk>   
            (?:
                # (?! [<>'"] ) 
                (?! > ) 
                \S
            ) +   
        )

        (?<might_white>     \s *   )

        (?<start_tag>  
            < (?&might_white) 
            img 
            \b       
        )

        (?<end_tag>          
            (?&html_end_tag)
          | (?&xhtml_end_tag)
        )

        (?<html_end_tag>       >  )
        (?<xhtml_end_tag>    / >  )

    )

}six;

$/ = undef;
$_ = <>;   # read all input

# strip stuff we aren't supposed to look at
s{ <!    DOCTYPE  .*?         > }{}sx; 
s{ <! \[ CDATA \[ .*?    \]\] > }{}gsx; 

s{ <script> .*?  </script> }{}gsix; 
s{ <!--     .*?        --> }{}gsx;

my $count = 0;

while (/$img_rx/g) {
    printf "Match %d at %d: %s\n", 
            ++$count, pos(), $+{TAG};
} 

你去吧。什么都没有!

Gee,为什么想要使用HTML解析类,因为在正则表达式中可以轻松处理HTML。 ☺

答案 1 :(得分:5)

Don't do it with regex。使用HTML / XML解析器。你甚至可以先通过Tidy来清理它。大多数语言都有一个Tidy库。你用的是哪种语言?

答案 2 :(得分:2)

这样做:

<img\s+src=\"[^\"]*?\">

或者您可以这样做以考虑任何其他属性

<img\s+[^>]*?\bsrc=\"[^\"]*?\"[^>]*>

答案 3 :(得分:0)

<img src=\"https?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?\">

PHP示例:

$prom = '<img src="http://foo"><img src="http://bar">';

preg_match_all('|<img src=\"https?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?\">|',$prom, $matches);

print_r($matches[0]);

答案 4 :(得分:0)

一种稍微疯狂/聪明/奇怪的方式就是分开&gt;&lt;然后在拆分后将两个字符分别添加回字符串。

$string = '<img src="http://foo"><img src="http://bar">';
$KimKardashian = split("><",$string);
$First = $KimKardashian[0] . '>';
$Second = '<' . $KimKardashian[1];