[javascript] RegExp.exec ()는 NULL을 산발적으로 반환합니다.

나는 이것에 대해 진지하게 미쳐 가고 있으며 나는 이미 여기서 무슨 일이 일어나고 있는지 파악하는 데 불균형 한 시간을 보냈습니다. 그러니 손 좀주세요 =)

JavaScript에서 문자열의 RegExp 일치를 수행해야합니다. 불행히도 매우 이상하게 작동합니다. 이 코드 :

var rx = /(cat|dog)/gi;
var w = new Array("I have a cat and a dog too.", "There once was a dog and a cat.", "I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.");

for (var i in w) {
    var m = null;
    m = rx.exec(w[i]);
    if(m){
        document.writeln("<pre>" + i + "\nINPUT: " + w[i] + "\nMATCHES: " + m.slice(1) + "</pre>");
    }else{
        document.writeln("<pre>" + i + "\n'" + w[i] + "' FAILED.</pre>");
    }
}

처음 두 요소에 대해 “cat”및 “dog”을 반환해야하지만 일부 exec()호출은를 반환하기 시작 null합니다. 이유를 모르겠습니다.

여기 에 코드를 실행하고 편집 할 수 있는 Fiddle을 게시했습니다 .

그리고 지금까지 Chrome과 Firefox에서 이것을 시도했습니다.

건배!

/ 크리스토퍼



답변

아, 여기 있습니다. 정규식 전역을 정의하고 있기 때문에 first cat와 일치 하고 loop의 두 번째 패스에서 일치 합니다 dog. 따라서 기본적으로 정규식 (내부 포인터)도 재설정하면됩니다. Cf. 이:

var w = new Array("I have a cat and a dog too.", "I have a cat and a dog too.", "I have a cat and a dog too.", "I have a cat and a dog too.");

for (var i in w) {
    var rx = /(cat|dog)/gi;
    var m = null;
    m = rx.exec(w[i]);
    if(m){
        document.writeln("<p>" + i + "<br/>INPUT: " + w[i] + "<br/>MATCHES: " + w[i].length + "</p>");
    }else{
        document.writeln("<p><b>" + i + "<br/>'" + w[i] + "' FAILED.</b><br/>" + w[i].length + "</p>");
    }
    document.writeln(m);
}


답변

정규식 객체에는 .NET lastIndex을 실행할 때 업데이트 되는 속성 이 있습니다 exec. 따라서 예를 들어 “나는 고양이와 개도 있습니다.” 에 대한 정규식 lastIndex을 실행하면 12로 설정됩니다. 다음 exec에 동일한 정규식 객체에서 실행하면 인덱스 12에서 찾기 시작합니다. 따라서 lastIndex속성 을 재설정해야 합니다. 각 실행 사이.


답변

두가지:

  1. (global) 플래그를 사용할 때 언급 된 재설정 필요성 g. 이 문제를 해결하기 위해 객체 0lastIndex구성원 에게 할당 하는 것이 RegExp좋습니다. 이것은 파괴 및 재생성보다 더 나은 성능을 제공합니다.
  2. 일부 라이브러리에서 예기치 않은 결과가 발생할 수 있으므로 객체 를 걷기 위해 키워드를 사용할inArray 때주의하십시오 . 때때로 당신은 isNaN(i).

코드는 다음과 같을 수 있습니다.

var rx = /(cat|dog)/gi;
w = ["I have a cat and a dog too.", "There once was a dog and a cat.", "I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat."];

for (var i in w)
 if(!isNaN(i))        // Optional, check it is an element if Array could have some odd members.
  {
   var m = null;
   m = rx.exec(w[i]); // Run
   rx.lastIndex = 0;  // Reset
   if(m)
    {
     document.writeln("<pre>" + i + "\nINPUT: " + w[i] + "\nMATCHES: " + m.slice(1) + "</pre>");
    } else {
     document.writeln("<pre>" + i + "\n'" + w[i] + "' FAILED.</pre>");
    }
  }


답변

/ g 만 사용하여 비슷한 문제가 발생했으며 여기에 제안 된 솔루션이 FireFox 3.6.8에서 작동하지 않았습니다. 내 스크립트가

var myRegex = new RegExp("my string", "g");

다른 사람이 위의 솔루션에서했던 것과 동일한 문제가있는 경우에 이것을 추가하고 있습니다.


답변