Регулярное выражение для разделения тегов HTML - PullRequest
2 голосов
/ 28 октября 2010

У меня есть строка HTML примерно так:

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

Каким будет шаблон регулярного выражения, чтобы разделить его на два отдельных тега img?

Ответы [ 5 ]

7 голосов
/ 28 октября 2010

Как вы уверены, что ваша строка точно это?А как насчет ввода, как это:

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

Какой это язык программирования?Есть ли какая-то причина, по которой вы не используете стандартный класс для анализа HTML-кода?Регулярные выражения - только хороший подход, когда у вас есть чрезвычайно известный набор входных данных.Они не работают для реального HTML, только для фальсифицированных демонстраций.

Даже если вы должны использовать регулярное выражение, вы должны использовать правильный грамматический.Это довольно просто.Я проверил следующие programacita на миллионе веб-страниц.Он заботится о случаях, которые я обрисовал в общих чертах выше - и один или два других тоже.

#!/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};
} 

Вот, пожалуйста.Ничего подобного!

Ну и дела, зачем вам когда-либо хотеть использовать класс HTML-парсинга, учитывая, как легко HTML может быть обработан в регулярном выражении.101

5 голосов
/ 28 октября 2010

Не делайте этого с регулярным выражением . Используйте анализатор HTML / XML. Вы можете даже запустить его через Tidy, чтобы очистить его. Большинство языков имеют библиотеку Tidy. Какой язык вы используете?

2 голосов
/ 28 октября 2010

Это сделает это:

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

Или вы можете сделать это для учета любых дополнительных атрибутов

<img\s+[^>]*?\bsrc=\"[^\"]*?\"[^>]*>
0 голосов
/ 12 декабря 2011

Один слегка безумный / блестящий / странный способ сделать это - разделить на> <и затем добавить два символа обратно в строку после разделения. </p>

$string = '<img src="http://foo"><img src="http://bar">';
$KimKardashian = split("><",$string);
$First = $KimKardashian[0] . '>';
$Second = '<' . $KimKardashian[1];
0 голосов
/ 28 октября 2010
<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]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...