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


87

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

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에서 이것을 시도했습니다.

건배!

/ 크리스토퍼


이 단지에 실패 할 "I have a cat and a dog too."것 같습니다
SilentGhost

exec는 일치가 의도적으로 실패하면 null을 반환하므로 어떤 이유로 일치하지 않습니다.
Martin Jespersen 2013 년

답변:


84

아, 여기 있습니다. 정규식 전역을 정의하고 있기 때문에 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);
}

우리는, 내가 :) 너무 느렸다이 있습니다
마틴 제스 퍼슨

아 달콤! 그것을 알아내는 데 시간이 좀 걸렸을 것입니다. 감사!
cpak

이로 인해 시간이 많이 절약되었습니다. 정말 고마워!
Thomas Johansen

이 문제는 내가 인생을 의심하게 만든다.
GZ Xue

내 월급을
돌려줘야

75

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


Bah,이 사이트는 나에게 너무 빠르다. +1 SilentGhost :-)
Frode

10
설명 해주셔서 감사합니다! myRe.lastIndex = 0;이후 사용을위한 설정으로 많은 도움이됩니다 .
Antony

1
와우, lastIndex에 대한 힌트에 감사드립니다. 정말 저를 미치게 만들었습니다!
dave0688

1
동일한 정규식 객체를 재사용하는 모범 사례를 따르기 때문에 이것이 정답이라고 생각합니다
smurtagh

이것이 정답이라는 데 동의하십시오. 동일한 정규식 객체를 재사용하고 내부 메커니즘도 설명합니다. OP는 변경을 고려해야합니다.
Sean Coley

34

두가지:

  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>");
    }
  }

1
정답이되어야합니다. 설정 rx.lastIndex = 0은 루프 내에서 RegEx 개체를 다시 만드는 것보다 훨씬 낫습니다.
Minoru

4

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

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

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.