regex로 XML과 HTML을 파싱하기 어려운 이유에 대한 몇 가지 예를 들어주실 수 있나요?
사람들이 반복해서 저지르는 한 가지 실수는 정규 표현식으로 XML이나 HTML을 구문 분석하려고 하는 것입니다.XML 및 HTML 구문 분석이 어려운 몇 가지 이유는 다음과 같습니다.
사용자는 파일을 일련의 줄로 취급하기를 원하지만 이는 유효합니다.
<tag
attr="5"
/>
사람들은 <또는 <tag>를 태그의 시작으로 취급하기를 원하지만, 이러한 것들은 야생에서 존재합니다.
<img src="imgtag.gif" alt="<img>" />
사람들은 종종 시작 태그와 끝 태그를 일치시키길 원하지만 XML과 HTML은 태그가 자신을 포함할 수 있도록 허용합니다(전통적인 리젝스는 전혀 처리할 수 없습니다).
<span id="outer"><span id="inner">foo</span></span>
사람들은 종종 문서의 내용(예: "주어진 페이지의 모든 전화번호 찾기" 문제)과 일치시키기를 원하지만, (보기 시 정상적으로 보이는 경우에도) 데이터가 표시될 수 있습니다.
<span class="phonenum">(<span class="area code">703</span>)
<span class="prefix">348</span>-<span class="linenum">3020</span></span>
주석에 형식이 불량하거나 불완전한 태그가 포함되어 있을 수 있습니다.
<a href="foo">foo</a>
<!-- FIXME:
<a href="
-->
<a href="bar">bar</a>
당신이 알고 있는 또 다른 것은 무엇입니까?
다음은 재미있는 유효 XML입니다.
<!DOCTYPE x [ <!ENTITY y "a]>b"> ]>
<x>
<a b="&y;>" />
<![CDATA[[a>b <a>b <a]]>
<?x <a> <!-- <b> ?> c --> d
</x>
그리고 이 작은 기쁨의 묶음은 유효한 HTML입니다.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd" [
<!ENTITY % e "href='hello'">
<!ENTITY e "<a %e;>">
]>
<title>x</TITLE>
</head>
<p id = a:b center>
<span / hello </span>
&<br left>
<!---- >t<!---> < -->
&e link </a>
</body>
잘못된 구문에 대한 모든 브라우저별 구문 분석은 말할 것도 없습니다.
행운을 빌어요!
편집(Jörg W Mittag):다음은 잘 형성되고 유효한 HTML 4.01의 또 다른 멋진 조각입니다.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<HTML/
<HEAD/
<TITLE/>/
<P/>
정말로.
<img src="imgtag.gif" alt="<img>" />
는 유효한 HTML이 아니며, 유효한 XML도 아닙니다.
'<' 및 '>'은 특성 문자열 안에 있는 유효한 문자가 아니므로 유효한 XML이 아닙니다.해당 XML 엔티티 < 및 >를 사용하여 탈출해야 합니다.
HTML에서는 short closing form이 허용되지 않기 때문에 유효한 HTML이 아닙니다(그러나 XML과 XHTML에서는 정확합니다).HTML 4.01 사양에 따라 'img' 태그도 암묵적으로 닫힌 태그입니다.이는 수동으로 닫는 것이 실제로는 잘못된 것이며, 다른 태그를 두 번 닫는 것과 동일하다는 것을 의미합니다.
HTML의 정확한 버전은
<img src="imgtag.gif" alt="<img>">
XHTML과 XML의 정확한 버전은
<img src="imgtag.gif" alt="<img>"/>
다음 예시 또한 유효하지 않습니다.
<
tag
attr="5"
/>
이것은 유효한 HTML이나 XML도 아닙니다.태그의 이름은 '<' 바로 뒤에 있어야 하지만 속성과 닫는 '>'는 원하는 곳에 있을 수 있습니다.그래서 유효한 XML은 실제로
<tag
attr="5"
/>
그리고 여기 또 다른 재미있는 것이 있습니다: 당신은 실제로 당신의 속성 인용 문자로 "또는 "를 사용할 수 있습니다.
<img src="image.gif" alt='This is single quoted AND valid!'>
게시된 다른 모든 이유는 맞지만 HTML 구문 분석의 가장 큰 문제는 사람들이 일반적으로 모든 구문 규칙을 정확하게 이해하지 못한다는 것입니다.브라우저에서 태그 그룹을 HTML로 해석한다고 해서 실제로 유효한 HTML을 작성한 것은 아닙니다.
편집: 그리고 심지어 stackoverflow.com 도 유효와 무효의 정의에 대해서는 저에게 동의합니다.유효하지 않은 XML/HTML이 강조 표시되지 않은 반면 수정된 버전은 강조 표시되지 않습니다.
기본적으로 XML은 정규 표현식으로 구문 분석되지 않습니다.하지만 그럴 이유도 없습니다.언어마다 XML 파서가 많이 있습니다.SAX 파서, DOM 파서, 풀 파서 중에서 선택할 수 있습니다.이 모든 것은 regexp로 파싱하는 것보다 훨씬 더 빠르며, 결과 DOM 트리에서 XPath나 XSLT와 같은 멋진 기술을 사용할 수 있습니다.
그러므로 제 대답은 다음과 같습니다. 정규 표현식으로 XML을 파싱하는 것은 어려울 뿐만 아니라 좋지 않은 생각입니다.수백만 개의 기존 XML 구문 분석기 중 하나만 사용하면 XML의 모든 고급 기능을 활용할 수 있습니다.
HTML은 스스로 파싱을 시도하기조차 너무 어렵습니다.첫째, 법적 구문에는 여러분이 모를 수도 있는 작은 미묘함들이 많이 있고, 둘째, 야생의 HTML은 엄청난 악취가 나는 더미일 뿐입니다(제 생각을 이해하세요).태그 수프처럼 HTML을 잘 다루는 다양한 느슨한 파서 라이브러리들이 있으니, 이것들을 사용하기만 하면 됩니다.
나는 이 주제에 대한 전체 블로그 항목을 작성했습니다: 정규 표현식 제한
문제의 핵심은 HTML과 XML이 적절하게 구문 분석하기 위해 계산 메커니즘을 필요로 하는 재귀적 구조라는 것입니다.진정한 정규군은 셀 수 없습니다.숫자를 세기 위해서는 문맥 자유 문법이 있어야 합니다.
앞 단락은 약간의 주의 사항과 함께 나옵니다.일부 정규적인 구현들은 이제 재귀의 개념을 지지합니다.그러나 정규 표현식에 재귀를 추가하기 시작하면 경계를 확장하는 것이므로 파서를 고려해야 합니다.
목록에 없는 한 가지 점은 속성이 순서에 상관없이 나타날 수 있기 때문에 정규 표현식이 href "foo" 및 클래스 "bar"와 연결되는 링크를 찾고 있다면 순서에 상관없이 제공될 수 있으며 그 사이에 다른 많은 것들이 있을 수 있다는 것입니다.
"파싱"이 무엇을 의미하는지에 따라 다릅니다.일반적으로 XML 문법은 규칙적이지 않기 때문에 regex를 사용하여 XML을 구문 분석할 수 없습니다.간단히 말하면 regex는 셀 수 없기 때문에(Perl regex는 실제로 사물을 셀 수 있을지도 모른다), 열린-닫힌 태그의 균형을 맞출 수 없습니다.
사람들이 regex를 사용하여 실수를 저지르는 것일까요, 아니면 단순히 그들이 달성하려고 하는 일에 충분할까요?
다른 사람들이 답변한 것처럼 regex를 사용하여 html과 xml을 파싱하는 것은 불가능하다는 것에 전적으로 동의합니다.
그러나 html/xml을 구문 분석하는 것이 아니라 html/xml의 "잘 알려진" 비트에서 작은 데이터 한 비트를 얻는 것이 요구된다면 정규식이나 심지어 더 간단한 "하위 문자열"도 충분합니다.
저는 "바퀴를 다시 발명하지 말라"고 말하고 싶습니다.XML이 정말, 정말 복잡한 형식이라는 점만 빼면 말입니다.그래서 아마 "싱크로트론을 재창조하지 말라"고 말해야 할 것 같습니다.
아마 올바른 상투적인 표현은 "망치만 가지고 있을 때" 시작할 것입니다.." 정규 표현식을 사용할 줄 알고, 정규 표현식은 구문 분석을 잘 하는데, XML 구문 분석 라이브러리를 배우는 이유는 무엇입니까?
XML 파싱이 어렵기 때문입니다.XML 구문 분석 라이브러리를 사용하는 방법을 배울 필요가 없으므로 절약하는 노력은 창의적인 작업과 버그 스왓팅을 통해 보충할 수 있을 것입니다.당신 자신을 위해 "XML 라이브러리"를 구글에 검색하고 다른 사람의 작업을 활용하세요.
사람들은 보통 탐욕스러운 패턴을 쓰는 것을 기본으로 하며, 종종 생각하지 못한 .* 파일 덩어리를 가능한 한 가장 큰 <foo>에 밀어 넣게 됩니다.*/foo>.
문제는 결국 다음과 같습니다.
정규 표현식은 거의 항상 부정확합니다.적법한 입력이 있으므로 올바르게 일치하지 못합니다.만약 여러분이 열심히 노력한다면 99%, 즉 99.999%를 정확하게 만들 수 있지만, XML이 개체를 사용함으로써 허용하는 이상한 것들 때문에 100%를 정확하게 만드는 것은 거의 불가능합니다.
입력의 0.00001%에 대해서도 정규 표현이 틀리면 보안 문제가 발생합니다. 이는 누군가가 응용 프로그램을 중단시키는 하나의 입력을 발견할 수 있기 때문입니다.
정규군이 99.99%의 경우를 처리할 수 있을 정도로 정확하다면 완전히 읽을 수 없고 유지보수할 수 없게 됩니다.
보통 크기의 입력 파일에서 정규화된 파일의 성능이 매우 떨어질 가능성이 높습니다.XML을 처음 접하게 된 것은 들어오는 XML 문서를 올바른 XML 파서로 구문 분석한 Perl 스크립트를 교체한 것입니다. 우리는 읽을 수 없는 코드 300줄을 누구나 이해할 수 있는 100줄로 교체했을 뿐만 아니라 사용자 응답 시간을 10초에서 약 0.1초로 향상시켰습니다.
이 고전에는 당신이 찾고 있는 정보가 있다고 생각합니다.거기에 있는 댓글 중 하나에서 핵심을 찾을 수 있습니다.
HTML은 Chomsky Type 2 문법(컨텍스트 프리 문법)이고 RegEx는 Chomsky Type 3 문법(정규표현)이라는 것이 여기의 결점이라고 생각합니다.Type 2 문법이 Type 3 문법보다 근본적으로 더 복잡하기 때문에 - 당신은 이것을 효과적으로 만들기를 바랄 수 없습니다.하지만 많은 사람들이 시도할 것이고, 어떤 사람들은 성공을 주장하고 다른 사람들은 잘못을 발견하고 여러분을 완전히 망칠 것입니다.
위키백과의 몇 가지 정보:촘스키 계층
저는 이 문제에 대해 간단히 답변을 드렸습니다.100%를 차지하는 것은 아니지만, 어떤 사전 가공 작업을 할 의향이 있다면 어떻게 가능한지 설명해 드립니다.
일반적으로 XML 문법은 규칙적이지 않기 때문에 regex를 사용하여 XML을 구문 분석할 수 없습니다.간단히 말하면 regex는 셀 수 없기 때문에(Perl regex는 실제로 사물을 셀 수 있을지도 모른다), 열린-닫힌 태그의 균형을 맞출 수 없습니다.
동의하지 않습니다.regex에서 recursive를 사용할 경우 열려 있는 태그와 닫기 태그를 쉽게 찾을 수 있습니다.
여기서 첫 번째 메시지에서 예제의 구문 분석 오류를 피하기 위해 regex 예제를 보여주었습니다.
언급URL : https://stackoverflow.com/questions/701166/can-you-provide-some-examples-of-why-it-is-hard-to-parse-xml-and-html-with-a-reg
'source' 카테고리의 다른 글
SASS - 여러 파일에 걸쳐 변수 사용 (0) | 2023.10.11 |
---|---|
WooCommerce 로그인 영역을 기본 Wordpress 로그인 양식으로 리디렉션 (0) | 2023.10.06 |
날짜 삽입 중 오류 발생 - 잘못된 날짜 값: (0) | 2023.10.06 |
데이터베이스의 원자 비교 및 스왑 (0) | 2023.10.06 |
관계형 데이터베이스에서 저장 프로시저 선택이 지원되지 않는 이유는 무엇입니까? (0) | 2023.10.06 |