2009-07-16 8 views
1

간단한 jQuery 연산을 사용하여 모든 앵커 태그와 해당 텍스트를 동적으로 일치시키고 페이지에 저장하려고했습니다. 그러나 이상한 행동을 발견했습니다. match() 또는 exec()를 사용할 때 바늘을 별도의 RegExp 객체 또는 패턴 변수로 지정하면 쿼리가 건초 더미에있는 수십 개의 인스턴스 중 하나와 일치합니다. 이Javascript Match 및 RegExp 문제 - 이상한 동작

match(/needle/gi) 

같은 패턴을 지정하는 경우

는 그리고 그것은 바늘의 모든 인스턴스와 일치합니다.

여기 내 코드입니다.

Firebug를 실행하고이 코드를이 페이지에서 바로 시도 할 수도 있습니다. 나를 위해

var a = {'text':'','parent':[]}; 

$("a").each(function(i,n) { 

    var module = $.trim($(n).text()); 
    a.text += module.toLowerCase() + ',' + i + ','; 

    a.parent.push($(n).parent().parent()); 

}); 

var stringLowerCase = 'b'; 

var regex = new RegExp(stringLowerCase, "gi"); 
//console.log(a.text); 
console.log("regex 1: ", regex.exec(a.text)); 

var regex2 = "/" + stringLowerCase + "/"; 
console.log("regex 2: ", a.text.match(regex2)); 

console.log("regex 3: ", a.text.match(/b/gi)); 

는 반환 :

regex 1: ["b"] 
regex 2: null 
regex 3: ["b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b"] 

사람이 문제의 루트를 설명 할 수 있습니까?

EDIT : regex1의 경우 전역 및 대소 문자를 구분하지 않고 일치시키기 위해 플래그 "gi"를 추가했는지 여부는 언급하지 않았습니다. 여전히 하나의 일치 항목 만 반환합니다.

EDIT2 : 내 자신의 문제가 해결되었습니다. 나는 여전히 하나의 정규 표현식이 오직 하나의 인스턴스와 매치되는 이유를 모르지만 match()와 regex1을 사용하여 모든 인스턴스를 매치시킬 수 있었다.

그래서이 모든 것이 동적으로 일치합니다!

var regex = new RegExp(stringLowerCase, "gi"); 
console.log("regex 2: ", a.text.match(regex)); 
+0

a.text의 내용은 무엇입니까? –

+0

은 두 개의 요소가있는 객체입니다. 코드 상단에 정의했습니다. 그 컨텍스트는 아마도 문서 객체 일 것이다. – picardo

답변

4

이것은 비정상적인 동작이 아닙니다. regex 1에서는/gi 인수를 사용하여 regex 3에서 항목의 모든 인스턴스를 반환하도록 지정한 곳에서 인스턴스 1 개만 확인합니다.

Regex 2에서는 "/ b /"===/b /가 아니라고 가정합니다. "/ b /"! ==/b /. "/ b /"는 문자열이 "/ b /"이면 "/ b /"가 반환되고 "/ b /"는 슬래시 사이를 검색해야한다는 것을 의미하므로 "abc"를 가질 수 있습니다. "b"를 반환하십시오

도움이되기를 바랍니다.

편집 :

그것으로 찾고은 조금 더의 exec 방법은 그것을 발견하는 모든 경기보다는 발견 한 첫 번째 일치를 반환합니다.

편집 :

var myRe = /ab*/g; 
var str = "abbcdefabh"; 
var myArray; 
while ((myArray = myRe.exec(str)) != null) 
{ 
    var msg = "Found " + myArray[0] + ". "; 
    msg += "Next match starts at " + myRe.lastIndex; 
    console.log(msg); 
} 

다시는 확실히 발견되는 첫 번째 인스턴스를 반환하지 그것을 살펴 가졌어요. 당신이 그것을 반복한다면 더 많은 것을 돌려 줄 것입니다.

왜 이렇게할까요? 나는 모르겠다 ... 내 JavaScript Kung Fu 명확하게 그 부분에 대답 할 정도로 강한 isnt 그

+0

나는 분명히 했어야했다. regx1의 경우 RegExp 객체의 정의에 "gi"를 추가해도 차이가 없습니다. 직접 해보십시오. – picardo

+0

그 이유는 알고 있습니까? RegExp 정의에 g 플래그를 추가 했으므로 전역 일치를 수행해야합니다. – picardo

0

regex2는 문자열이며 RegExp가 아니며 이런 종류의 구문을 사용하는 데 문제가있었습니다. 실제로 그 동작을 잘 모르겠습니다.

편집 : Remebered : regex2의 경우 JS는 "b"가 아닌 "/ b /"를 바늘로 찾습니다.

+0

하지만 regex1은 어떻습니까? 그것은 효과가 있었을 것입니다. 어떻게 문제를 해결하게 되었습니까? – picardo

2

이유는 regex 2 null을 반환하는 이유는 당신이 "/ b /"패턴 매개 변수로 전달하는 것입니다 "b" 실제로 실제로 패턴의 일부인 유일한 것입니다. 슬래시는 []가 배열을 가리키는 것처럼 정규 표현식의 약식입니다. 그래서 만약 당신이 그것을 새로운 regex ("b")로 대체한다면, 그 예에서 "global + ignorecase"플래그를 생략하기 때문에, 하나의 match 만 얻을 것입니다. # 2 및 # 3에 대해 동일한 결과를 얻으려면 그에 따라 수정하십시오.

var regex2 = stringLowerCase; 
console.log("regex 2: ", a.text.match(regex2, "gi")); 
console.log("regex 3: ", a.text.match(/b/gi));