JavaScript Regexp에서 임의의 수의 그룹을 캡처하는 방법은 무엇입니까?


84

이 JavaScript 줄을 기대합니다.

"foo bar baz".match(/^(\s*\w+)+$/)

다음과 같이 반환합니다.

["foo bar baz", "foo", " bar", " baz"]

대신 마지막으로 캡처 된 일치 만 반환합니다.

["foo bar baz", " baz"]

캡처 한 모든 경기를 얻을 수있는 방법이 있습니까?

답변:


93

캡처 그룹을 반복하면 대부분의 플레이버에서 마지막 캡처 만 유지됩니다. 이전 캡처를 덮어 씁니다. 예를 들어 .NET과 같은 일부 버전에서는 모든 중간 캡처를 가져올 수 있지만 Javascript에서는 그렇지 않습니다.

즉, Javascript에서 N 캡처 링 그룹 이있는 패턴이있는 경우 일부 그룹이 반복 되더라도 일치 당 정확히 N 개의 문자열 만 캡처 할 수 있습니다 .

따라서 일반적으로 수행해야 할 작업에 따라 다음과 같이 말합니다.

  • 옵션 인 경우 대신 구분 기호로 분할
  • 일치하는 대신 루프 에서 /(pattern)+/일치 할 /pattern/g수도 있습니다.exec
    • 이 두 가지는 정확히 동일하지는 않지만 옵션 일 수 있습니다.
  • 다단계 일치 수행 :
    • 한 경기에서 반복되는 그룹 캡처
    • 그런 다음 다른 정규식을 실행하여 해당 일치를 분리하십시오.

참고 문헌


다음 <some;words;here>exec루프를 사용하여 텍스트 를 일치 시킨 다음 분할하여 ;개별 단어를 얻는 예입니다 ( ideone.com 참조 ).

var text = "a;b;<c;d;e;f>;g;h;i;<no no no>;j;k;<xx;yy;zz>";

var r = /<(\w+(;\w+)*)>/g;

var match;
while ((match = r.exec(text)) != null) {
  print(match[1].split(";"));
}
// c,d,e,f
// xx,yy,zz

사용되는 패턴은 다음과 같습니다.

      _2__
     /    \
<(\w+(;\w+)*)>
 \__________/
      1

이 경기는 <word>, <word;another>, <word;another;please>, 등의 그룹이 단어의 수를 캡처 반복하지만 마지막 캡처를 유지할 수 있습니다. 전체 단어 목록은 그룹 1에 의해 캡처됩니다. 이 문자열은 split세미콜론 구분 기호에 있습니다.

관련 질문


7

이건 어때? "foo bar baz".match(/(\w+)+/g)


코드는 작동하지만 내 예제에 전역 플래그를 추가해도 문제가 해결되지 않습니다. "foo bar baz".match (/ ^ (\ s * \ w +) + $ / g)는 [ "foo bar baz"]를 반환합니다.
disc0dancer 2010-08-21

아래 @Jet의 정규식으로 변경하면 작동합니다. "foo bar baz".match(/\w+/g) //=> ["foo", "bar", "baz"]. 앞에있는 일치하는 문자열을 무시하지만 여전히 합리적인 대안입니다.
Jed Schneider

6

문자열을 분할하는 방법에 대해 더 복잡한 요구 사항이없는 경우 문자열을 분할 한 다음 초기 문자열을 반환 할 수 있습니다.

var data = "foo bar baz";
var pieces = data.split(' ');
pieces.unshift(data);

1
이것은 적어도 현재 응용 프로그램에 대해 split ()보다 더 정교한 것은 필요하지 않다는 사실을 깨우는 데 필요한 조언의 일부였습니다.
Hephaestus 2014 년

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