2009-03-20 3 views
4

HTML 파일에서 사용되지 않은 스팬 (예 : 속성이없는 스팬)을 제거하려고합니다. 다른 정규식과 함께 사용하지 않으려했던 모든 속성을 이미 정리했습니다.Perl 정규식으로 사용되지 않는 중첩 HTML span 태그를 제거하려면 어떻게해야합니까?

내 정규식에서 올바른 시작 및 종료 태그 쌍을 선택하지 못하는 문제가 있습니다.

my $a = 'a <span>b <span style="color:red;">c</span> d</span>e'; 
$a =~ s/<span\s*>(.*?)<\/span>/$1/g; 
print "$a\ 

반환

a b <span style="color:red;">c d</span>e 

그러나 나는 감사

a b <span style="color:red;">c</span> de 

도움말을 반환합니다.

+0

계란, 소시지 구운 콩 Schwern

답변

11

HTML::Parser을보십시오 : 내가 필요한 모든 기능을 수행하는 스크립트를 출판 한 모든 당신의 도움으로

#!/usr/bin/perl 

use strict; 
use warnings; 

use HTML::Parser; 

my @print_span; 
my $p = HTML::Parser->new(
    start_h => [ sub { 
    my ($text, $name, $attr) = @_; 
    if ($name eq 'span') { 
     my $print_tag = %$attr; 
     push @print_span, $print_tag; 
     return if !$print_tag; 
    } 
    print $text; 
    }, 'text,tagname,attr'], 
    end_h => [ sub { 
    my ($text, $name) = @_; 
    if ($name eq 'span') { 
     return if !pop @print_span; 
    } 
    print $text; 
    }, 'text,tagname'], 
    default_h => [ sub { print shift }, 'text'], 
); 
$p->parse_file(\*DATA) or die "Err: $!"; 
$p->eof; 

__END__ 
<html> 
<head> 
<title>This is a title</title> 
</head> 
<body> 
<h1>This is a header</h1> 
a <span>b <span style="color:red;">c</span> d</span>e 
</body> 
</html> 
+0

대단히 감사합니다. 나는 당신이 이것을 어떻게했는지에 관해 알아야 할 것이고, 나는 처리 할 여분의 합병증이있다. 그러나 잘하면이 트릭을 할 것이다. 목표는 실제로 masterpages와 함께 asp.net 파일에 붙여 넣은 단어 쓰레기를 정리하는 것입니다. –

6

처리를 위해 regexps를 사용하지 마십시오 (HTML ==) XML. 당신은 어떤 입력을 받을지 결코 알 수 없습니다. 이 유효한 HTML을 고려해보십시오.

a <span>b <span style="color:red;" title="being closed with </span>">c</span> de 

생각 해 봤나요?

대신 XML 프로세서를 사용하십시오.

또한 을 참조하십시오. 관련 질문 (오른쪽).

+0

것이 사실이지만이 운이 좋게 I는 청소 cruddy HTML의 더미 (대형 임에도 불구하고) 알려져 있으며, 그 중 하나가 아닌 한 단어의 많은 악의 속임수 –

+0

그것이 단어에 관한 : 당신은 이것을 보았는가 : Word의 불쾌한 HTML을 청소, http://www.codinghorror.com/blog/archives/000485.html? –

+0

HTML은 유효하지 않습니다. '<' and '>'은 속성에서 이스케이프되어야하며, 두번째 span은 닫히지 않습니다. – tig

9

정규 표현식으로 HTML (또는 XML)을 구문 분석하기에 충분하지 않습니다. regex가 나오면 올바른 HTML (심지어 실제 태그 수프는 말할 것도 없다)의 다양한 공식과 일치하지 않을 것이다.

이것은 중첩 문제입니다. Regex는 일반적으로 중첩을 전혀 처리 할 수 ​​없지만 Perl은 regex 재귀를 지원하는 비표준 확장을가집니다. 여기서 (n은) 재귀 할 그룹 번호입니다. 따라서이 같은 귀하의 예를 모두 스팬을 일치합니다 :

(<span[^>]*>.*+(?1)?.*+<\/span>) 

perlfaq 6.11를 참조하십시오.

유감스럽게도 이것은 충분하지 않습니다. 왜냐하면 </span> 끝 태그를 닫을 수 있도록 < span> 시작 태그를 계산할 수 있어야하기 때문입니다. 나는 span- start-tags 스팬과 일치하지 않으면이 방법을 생각할 수 없다.

HTML 파서가 필요합니다. HTML/XML 용 정규 표현식이 분명히 잘못 되었기 때문에 어쨌든 사용해야합니다.

관련 문제