문제

Perl에서 정규 표현식을 사용하여 모든 태그를 일치시키고 제거해야합니다.다음이 있습니다. 라코 디스

그러나 이것은 여전히 닫는 </p> 태그와 일치합니다.닫는 태그와 일치하는 방법에 대한 힌트도 있나요?

참고, 이것은 xhtml에서 수행됩니다.

도움이 되었습니까?

해결책 3

내가 생각해 낸 것 : 라코 디스

이제 속성이 있거나없는 p 태그와 닫는 p 태그를 처리하지만 속성이 있거나없는 사전 및 유사한 태그와 일치합니다.

속성을 제거하지는 않지만 내 소스 데이터는 속성을 입력하지 않습니다. 나중에이 작업을 수행하도록 변경할 수 있지만 지금은 이것으로 충분합니다.

다른 팁

정규식 사용을 고집 하는 경우 대부분의 경우 다음과 같이 작동합니다. 라코 디스

설명 : 라코 디스

하지만 실제로는 두통을 덜고 대신 파서를 사용하십시오. CPAN에는 적합한 여러 모듈이 있습니다. 다음은 HTML :: TokeParser 모듈을 사용하는 예입니다. 매우 뛰어난 HTML :: Parser CPAN 배포와 함께 제공 : 라코 디스

HTML :: Parser 는 파일 이름 형식으로 입력을받습니다. 파일 핸들 또는 문자열. 위 코드를 라이브러리에 래핑하고 대상을 구성 가능하게 만드는 것은 어렵지 않습니다. 결과는 정규 표현식을 사용하는 것보다 훨씬 더 안정적이고 유지 관리 가능하며 더 빠를 것입니다 (HTML :: Parser는 C 기반 백엔드를 사용함).

내 생각에는 HTML 파서 이외의 다른 것으로 HTML을 파싱하려는 것은 고통의 세계를 요구하는 것입니다.HTML은 정말 복잡한 언어입니다 (XHTML이 만들어진 주요 이유 중 하나이며 HTML보다 훨씬 간단합니다).

예 : 라코 디스

완전하고 100 % 잘 구성된 100 % 유효한 HTML 문서입니다.(음, DOCTYPE 선언이 누락되었지만 그 외에는 ...)

의미 상 라코 디스

그러나 그럼에도 불구하고 다루어야 할 것은 유효한 HTML입니다.물론 정규식을 고안하여 파싱 할 수는 수도 있지만 다른 사람들이 이미 제안했듯이 실제 HTML 파서를 사용하는 것이 훨씬 더 쉽습니다.

이 작업을 수행하려는 이유가 확실하지 않습니다. HTML 정리를위한 정규식이 항상 최선의 방법은 아닙니다 (속성 등을 정리하고 javascript : hrefs 등을 제거하는 것을 기억해야 함) ...하지만 정규식<p></p>가 아닌 HTML 태그와 일치 :

(<[^pP].*?>|</[^pP]>)

자세히 : 라코 디스

Xetius 정규식을 사용했는데 제대로 작동합니다.일부 플렉스 생성 태그를 제외하고는 다음과 같습니다.
내부에 공백이 없습니다. \ s 후에 간단한 ? 으로 문제를 해결하려고했는데 제대로 작동하는 것 같습니다. 라코 디스

플렉스 생성 html 텍스트에서 태그를 지우는 데 사용하고 있으므로 예외 태그도 더 추가했습니다. 라코 디스

HTML은 정규 언어가 아니기 때문에 정규 표현식이 일치하는 데 매우 효과적 일 것으로 기대하지 않습니다.그들은이 작업에 달렸을 수도 있지만 (확신하지는 않지만) 다른 곳을 찾는 것을 고려할 것입니다.perl은 HTML을 조작하기위한 일부 기성 라이브러리를 가지고 있어야한다고 확신합니다.

어쨌든, 나는 당신이 일치시키고 싶은 것이 탐욕스럽지 않다고 생각할 것입니다 (펄의 정규 표현식 구문의 변덕을 모릅니다.더 이상 도울 수 없습니다).\ s는 공백을 의미한다고 가정합니다.아마도 그렇지 않을 것입니다.어느 쪽이든, 공백으로 태그 이름에서 오프셋 된 속성과 일치하는 것을 원합니다.그러나 사람들은 종종 스크립트와 주석 안에 이스케이프 처리되지 않은 꺾쇠 괄호를 넣거나 일치시키고 싶지 않은 따옴표로 묶은 속성 값을 넣는 경우가 많습니다.

내가 말했듯이 정규 표현식이 작업에 적합한 도구라고 생각하지 않습니다.

Since HTML is not a regular language

HTML isn't but HTML tags are and they can be adequatly described by regular expressions.

Assuming that this will work in PERL as it does in languages that claim to use PERL-compatible syntax:

/<\/?[^p][^>]*>/

EDIT:

But that won't match a <pre> or <param> tag, unfortunately.

This, perhaps?

/<\/?(?!p>|p )[^>]+>/

That should cover <p> tags that have attributes, too.

You also might want to allow for whitespace before the "p" in the p tag. Not sure how often you'll run into this, but < p> is perfectly valid HTML.

The original regex can be made to work with very little effort:

 <(?>/?)(?!p).+?>

The problem was that the /? (or \?) gave up what it matched when the assertion after it failed. Using a non-backtracking group (?>...) around it takes care that it never releases the matched slash, so the (?!p) assertion is always anchored to the start of the tag text.

(That said I agree that generally parsing HTML with regexes is not the way to go).

Xetius, resurrecting this ancient question because it had a simple solution that wasn't mentioned. (Found your question while doing some research for a regex bounty quest.)

With all the disclaimers about using regex to parse html, here is a simple way to do it.

#!/usr/bin/perl
$regex = '(<\/?p[^>]*>)|<[^>]*>';
$subject = 'Bad html <a> </I> <p>My paragraph</p> <i>Italics</i> <p class="blue">second</p>';
($replaced = $subject) =~ s/$regex/$1/eg;
print $replaced . "\n";

See this live demo

Reference

How to match pattern except in situations s1, s2, s3

How to match a pattern unless...

Try this, it should work:

/<\/?([^p](\s.+?)?|..+?)>/

Explanation: it matches either a single letter except “p”, followed by an optional whitespace and more characters, or multiple letters (at least two).

/EDIT: I've added the ability to handle attributes in p tags.

You should probably also remove any attributes on the <p> tag, since someone bad could do something like:

<p onclick="document.location.href='http://www.evil.com'">Clickable text</p>

The easiest way to do this, is to use the regex people suggest here to search for &ltp> tags with attributes, and replace them with <p> tags without attributes. Just to be on the safe side.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top