[regex] 정규 표현식을 사용하여 HTML 구문 분석 : 왜 안되나요?

asker가 HTML에서 일부 정보를 가져 오기 위해 정규식을 사용하는 stackoverflow에 대한 모든 질문은 필연적으로 HTML을 구문 분석하기 위해 정규식을 사용하지 않는다는 “응답”을 갖습니다.

왜 안돼? Beautiful Soup 과 같이 인용 부호가없는 “실제”HTML 파서가 있다는 것을 알고 있으며 , 강력하고 유용하다고 확신하지만, 간단하고 빠르거나 더러운 일을하는 이유는 무엇입니까? 몇 가지 정규 표현식 문이 제대로 작동 할 때 너무 복잡한 것을 사용하는 것을 귀찮게합니까?

또한, 정규 표현식에 대해 이해하지 못하는 근본적인 것이 있습니까? 일반적으로 구문 분석하기에 나쁜 선택입니다.



답변

정규 표현식에서는 전체 HTML 구문 분석을 수행 할 수 없습니다. 정규 표현식에서는 불가능한 여는 태그와 닫는 태그의 일치에 따라 달라집니다.

정규식은 정규 언어 와 만 일치 할 수 있지만 HTML은 문맥이없는 언어 이며 정규 언어가 아닙니다 (@StefanPochmann이 지적했듯이, 정규 언어도 문맥이 없으므로 문맥이없는 것이 반드시 정규가 아니라는 것은 아닙니다). HTML에서 정규 표현식으로 할 수있는 유일한 방법은 휴리스틱이지만 모든 조건에서 작동하지는 않습니다. 정규식과 일치하지 않는 HTML 파일을 표시 할 수 있어야합니다.


답변

신속하게 더러워지면 정규 표현식이 잘 수행됩니다. 그러나 알아야 할 기본 사항 은 올바르게 정규 표현식을 구성하는 것이 불가능 하다는 것입니다. HTML 구문 분석 입니다.

그 이유는 정규 표현식이 임의로 중첩 된 표현식을 처리 할 수 ​​없기 때문입니다. 정규식을 사용하여 중첩 패턴을 일치시킬 수 있습니까?를 참조하십시오 .


답변

( http://htmlparsing.com/regexes에서 )

<img> 태그에서 URL을 추출하려고하는 HTML 파일이 있다고 가정합니다.

<img src="http://example.com/whatever.jpg">

따라서 Perl에서 다음과 같은 정규식을 작성하십시오.

if ( $html =~ /<img src="(.+)"/ ) {
    $url = $1;
}

이 경우 $url실제로 포함합니다
http://example.com/whatever.jpg. 그러나 다음과 같이 HTML을 시작하면 어떻게됩니까?

<img src='http://example.com/whatever.jpg'>

또는

<img src=http://example.com/whatever.jpg>

또는

<img border=0 src="http://example.com/whatever.jpg">

또는

<img
    src="http://example.com/whatever.jpg">

또는 당신은에서 오 탐지를 시작합니다

<!-- // commented out
<img src="http://example.com/outdated.png">
-->

매우 단순 해 보이고 변경되지 않은 단일 파일의 경우 단순 할 수 있지만 임의의 HTML 데이터에서 수행하려는 모든 작업에 대해 정규 표현식은 미래의 상심을위한 레시피 일뿐입니다.


답변

두 가지 빠른 이유 :

  • 악의적 인 입력에 견딜 수있는 정규 표현식을 작성하는 것은 어렵습니다. 사전 제작 된 도구를 사용하는 것보다 더 어려운 방법
  • 필연적으로 붙어있을 어리석은 마크 업으로 작업 할 수있는 정규 표현식을 작성하는 것은 어렵습니다. 사전 제작 된 도구를 사용하는 것보다 더 어려운 방법

일반적으로 구문 분석에 대한 정규 표현식의 적합성과 관련하여 적합하지 않습니다. 대부분의 언어를 구문 분석하는 데 필요한 정규 표현식을 본 적이 있습니까?


답변

구문 분석이 진행되는 한 정규 표현식은 입력이 토큰으로 분류되는 “어휘 분석”(렉서) 단계에서 유용 할 수 있습니다. 실제 “구문 분석 트리 작성”단계에서는 그다지 유용하지 않습니다.

HTML 파서의 경우, 잘 구성된 HTML 만 허용하고 정규 표현식이 수행 할 수있는 기능 이외의 기능이 필요합니다 (“계산”할 수 없으며 주어진 수의 여는 요소가 동일한 수로 균형을 유지하는지 확인하십시오) 닫는 요소).


답변

브라우저가 다소 자유로운 방식으로 처리하는 HTML을 “나사”하는 방법은 많지만 모든 경우를 정규식으로 처리하기 위해 브라우저의 자유로운 동작을 재현하는 데 약간의 노력이 필요하므로 정규 표현식은 필연적으로 일부 특별한 경우 실패합니다. 이 경우 시스템에 심각한 보안 격차가 발생할 수 있습니다.


답변

문제는 HTML 및 정규식과 관련된 질문을하는 대부분의 사용자가 작동하는 자체 정규식을 찾을 수 없기 때문에이 작업을 수행한다는 것입니다. 그런 다음 DOM 또는 SAX 파서 또는 이와 유사한 것을 사용할 때 모든 것이 더 쉬운 지 생각해야합니다. XML과 유사한 문서 구조로 작업하기 위해 최적화되고 구성됩니다.

물론 정규식으로 쉽게 해결할 수있는 문제가 있습니다. 그러나 강조는 쉽게 이루어 집니다.

http://.../정규 표현식으로 잘 보이는 것처럼 보이는 모든 URL을 찾으려면 . 그러나 클래스가 ‘mylink’인 a-Element에있는 모든 URL을 찾으려면 적절한 파서를 사용하는 것이 좋습니다.