2012-02-05 3 views
-3

------------- test.hta 파일 코드 ------------왜이 자바 스크립트 RegExp 구문은 무한 루프가 될 것입니까?

<!DOCTYPE html> 
<html> 
<head> 
<title>dead</title> 
</head> 
<body> 
txt<textarea id="content" > 
      <input name="" type="text" class="qu_te1n05ew" value="请输入您的E-mail地址" /> 
      <input name="" type="submit" class="qu_sbt02" value="提 交" /> 
      </textarea> 
<button onclick="startCls();">start</button> 

<script> 
function getObj(id) { 
    return 'string' == typeof id ? document.getElementById(id) : id; 
} 

function startCls() { 
    var txt = getObj('content').value; 
    var srcRe = /<\w+(?:\s[^<>]*(?:(?:'[^']*')|(?:"[^"]*"))?[^<>]*)*\s+src\s*\=\s*["']?(?:[^"' <>]*\/)?([^\/"'<>]+\.(?:gif|jpg|png))['" ](?:\s[^<>]*(?:(?:'[^']*')|(?:"[^"]*"))?[^<>]*)*\/?>/ig; 
    alert(srcRe.exec(txt)); 
} 
</script> 
</body> 
</html> 

----------- -code end -------

srcRe.exec(txt) 왜 루프가 죽었는지? 다른 테스트 문자열이 작동합니다.

내 평균 >을 종료하지 않는 HTML을 tagname.have하지 않기 때문에하는 img 태그 이름의 SRC를 얻을 수와 파일 이름을 얻기 위해 그것을 분할하지만, <b><img src="ss.gif" </b>처럼, 아니 태그 이름의 SRC를하지 않는 인 srcRe;

이 SYNAX (?:\s[^<>]*(?:(?:'[^']*')|(?:"[^"]*"))?[^<>]*)*, 평균이 < 또는 >이 경우, 그것은 '' 또는 ""에 있어야하고, 다른 문자열은하지 < 또는 >해야하며, >에 의해 <, 말 시작된다

+0

이제 두 번 투표 할 의견이 있습니다. – gideon

+1

['TEXTAREA'] (http://www.w3.org/TR/html4/interact/forms.html#edef-TEXTAREA)는 구문 분석 된 문자 데이터 만 허용하지만 다른 태그는 허용하지 않습니다. – Gumbo

+0

죄송합니다. 그러나 정규 표현식을 사용하는 사람은 누구나 그 결과를받을 자격이 있습니다. 그것은 내가 몇 주 동안 본 코드 중 가장 이해하기 어려운 코드 라인입니다. 나는 당신이 훨씬 더 읽기 쉽고, 유지 보수가 가능하며, 당신이 가진 이슈를 가지지 않는 다른 방법 (실제 JS를 작성하여 그것을 쓰는 것)을 제안한다. – jfriend00

답변

2

나는이 무시 무시한 정규식을 디버깅하지 않을 것입니다. 하지만 왜 실패하는지 말할 수 있습니다. "가독성"을 위해 그것을 분해 : 당신은 당신의 문자열에 .gif 또는 .jpg 또는 .png가있을 경우에만 일치 할 수 있음을 알 수

< 
\w+ 
(?:\s[^<>]*(?:(?:'[^']*')|(?:"[^"]*"))?[^<>]*)* 
\s+src\s*\=\s*["']? 
(?:[^"' <>]*\/)? 
([^\/"'<>]+\.(?:gif|jpg|png)) 
['" ] 
(?:\s[^<>]*(?:(?:'[^']*')|(?:"[^"]*"))?[^<>]*)* 
\/? 
> 

. 그래서 정규 표현식은 실패해야합니다.

문자열에 [^<>]*의 인스턴스가 여러 개 있기 때문에 정규식 엔진이이 문제를 파악하는 데 오랜 시간이 걸리며 문제는 전체 태그의 내용을 모두 일치시킬 수 있고 (또 시도 할 수도 있음) 상해에 모욕을 더하십시오) 모두는 반복 그룹으로 동봉됩니다. 세분화 라인 3을 참조하십시오 :

(?: 
\s 
[^<>]*  # optional! 
(?: 
    (?:'[^']*') 
    | 
    (?:"[^"]*") 
)?   # optional! 
[^<>]*  # optional! 
)*   # optional! 

는 정규식 엔진의 모든 실패를 선언 할 수있는 전에 확인하는 순열의 gazillions있다. 간단히 말해서, 그것은 무한 루프가 아니지만 이와 같은 입력과 함께 정규 표현식은 지옥이 얼어 붙을 때까지 컴퓨터를 바쁘게 유지하려고합니다.

힌트 1 : catastrophic backtracking에서이 자습서를 읽으십시오.
힌트 2 : 정규식을 사용하여 HTML을 구문 분석하지 마십시오. 적어도 당신이 know exactly what you're doing이 아니라면.

+0

''''s.gif'를 얻기 위해 정규 표현식을 쓰고,''이 태그에 포함될 수 있는지 확인하십시오.하지만 이제는'regExp'로 수행하기가 어렵습니다. 내 프로젝트에서, 내가 원하는 것을하기 위해 간단한 정규 표현식을 쓸 수 있습니다. 내 영어가 너무 나빠요, 재앙적인 백 트랙킹 웹, __ 다음 댓글보기 – qidizi

+0

나는 절반 이상을 이해할 수 있으며''. – qidizi

+0

또 다른 방법은'innnerHTML'과'getElementsByTagName ('*')'이며 whice 요소가 img인지를 결정하기 위해'for'를 사용하고 img를 얻습니다. – qidizi

관련 문제