[javascript] JavaScript 정규식에서 캡처 그룹을 지정 했습니까?

내가 아는 한 JavaScript에는 캡쳐 그룹이라는 것과 같은 것이 없습니다. 유사한 기능을 얻는 다른 방법은 무엇입니까?



답변

ECMAScript 2018에서는 명명 된 캡처 그룹 을 JavaScript 정규식에 도입했습니다 .

예:

  const auth = 'Bearer AUTHORIZATION_TOKEN'
  const { groups: { token } } = /Bearer (?<token>[^ $]*)/.exec(auth)
  console.log(token) // "Prints AUTHORIZATION_TOKEN"

구형 브라우저를 지원 해야하는 경우 명명 된 캡처 그룹으로 할 수있는 일반 (번호 매기기) 캡처 그룹으로 모든 작업을 수행 할 수 있습니다. 번호를 추적하면됩니다-그룹에서 그룹을 캡처하는 순서가 번거 롭다면 번거로울 수 있습니다 정규식 변경.

내가 생각할 수있는 명명 된 캡처 그룹의 두 가지 “구조적”장점은 다음과 같습니다.

  1. 일부 정규 표현식 맛 (내가 아는 한 .NET 및 JGSoft)에서는 정규 표현식의 다른 그룹에 동일한 이름을 사용할 수 있습니다 ( 여기에서 중요한 예는 여기 참조 ). 그러나 대부분의 정규 표현식은이 기능을 지원하지 않습니다.

  2. 숫자로 둘러싸인 상황에서 번호가 매겨진 캡처 그룹을 참조해야하는 경우 문제가 발생할 수 있습니다. 하자 당신이 자리에 0을 추가 할 따라서 교체 할 말 (\d)과 함께 $10. 자바 스크립트,이 의지 (당신이 당신의 정규식에서 10 개 미만의 캡처 그룹을 가지고 같은) 작동하지만 펄은 역 참조 번호를 찾고 있다고 생각합니다 10대신 숫자의 1다음에 0. Perl에서는 ${1}0이 경우에 사용할 수 있습니다 .

그 외에, 명명 된 포획 그룹은 단지 “구문 설탕”이다. 캡처 그룹은 실제로 필요할 때만 사용 (?:...)하고 다른 모든 상황에서는 캡처되지 않은 그룹을 사용하는 데 도움이됩니다 .

JavaScript의 더 큰 문제는 (제 생각에) 읽기 쉬운 복잡한 정규 표현식을 훨씬 쉽게 만들 수있는 자세한 정규 표현식을 지원하지 않는다는 것입니다.

Steve Levithan의 XRegExp 라이브러리 는 이러한 문제를 해결합니다.


답변

추가 구문, 플래그 및 메소드에 대한 지원을 포함하여 정규 표현식의 확장되고 확장 가능한 크로스 브라우저 구현 인 XRegExp 를 사용할 수 있습니다 .

  • 명명 된 캡처에 대한 포괄적 인 지원을 포함하여 새로운 정규식 및 대체 텍스트 구문을 추가합니다 .
  • 두 개의 새로운 정규식 플래그 추가 : s도트하는 모든 문자와 일치하기를 (일명 DOTALL 또는 만일 Singleline 모드) 및 x자유 공간과 의견 (일명 확장 모드)에 대한.
  • 복잡한 정규식 처리를 간편하게 수행 할 수있는 기능 및 방법 모음을 제공합니다.
  • 정규식 동작 및 구문에서 가장 일반적으로 발생하는 크로스 브라우저 불일치를 자동으로 수정합니다.
  • XRegExp의 정규 표현식 언어에 새로운 구문과 플래그를 추가하는 플러그인을 쉽게 만들고 사용할 수 있습니다.

답변

또 다른 가능한 해결책 : 그룹 이름과 색인을 포함하는 객체를 만듭니다.

var regex = new RegExp("(.*) (.*)");
var regexGroups = { FirstName: 1, LastName: 2 };

그런 다음 객체 키를 사용하여 그룹을 참조하십시오.

var m = regex.exec("John Smith");
var f = m[regexGroups.FirstName];

이것은 정규 표현식의 결과를 사용하여 코드의 가독성 / 품질을 향상 시키지만 정규 표현식 자체의 가독성은 향상시키지 않습니다.


답변

ES6에서는 배열 파괴를 사용하여 그룹을 잡을 수 있습니다.

let text = '27 months';
let regex = /(\d+)\s*(days?|months?|years?)/;
let [, count, unit] = regex.exec(text) || [];

// count === '27'
// unit === 'months'

주의:

  • 마지막의 첫 번째 쉼표 let는 결과 배열의 첫 번째 값을 건너 뜁니다. 이는 전체 일치 문자열입니다.
  • || []후에는 .exec()더 일치 (때문에이없는 경우 destructuring 오류를 방지 할 수 .exec()반환됩니다 null)

답변

업데이트 : 마침내 JavaScript로 만들었습니다 (ECMAScript 2018)!


명명 된 캡처 그룹은 곧 JavaScript로 만들 수 있습니다.
이에 대한 제안은 이미 3 단계에 있습니다.

캡처 그룹에는 (?<name>...)식별자 이름에 대한 구문을 사용하여 각괄호 안에 이름을 지정할 수 있습니다 . 날짜의 정규 표현식은로 쓸 수 있습니다 /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u. 각 이름은 고유해야하며 ECMAScript IdentifierName 의 문법을 따라야합니다 .

명명 된 그룹은 정규식 결과의 그룹 속성의 속성에서 액세스 할 수 있습니다. 명명되지 않은 그룹과 마찬가지로 그룹에 대한 번호가 지정된 참조도 작성됩니다. 예를 들면 다음과 같습니다.

let re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u;
let result = re.exec('2015-01-02');
// result.groups.year === '2015';
// result.groups.month === '01';
// result.groups.day === '02';

// result[0] === '2015-01-02';
// result[1] === '2015';
// result[2] === '01';
// result[3] === '02';


답변

캡처 된 그룹의 이름을 지정하면 복잡한 정규식과의 혼동이 줄어 듭니다.

실제로 사용 사례에 따라 다르지만 정규 표현식을 인쇄하면 도움이 될 수 있습니다.

또는 캡처 된 그룹을 참조하기 위해 상수를 시도하고 정의 할 수 있습니다.

그런 다음 주석은 코드를 읽는 다른 사람, 수행 한 작업을 표시하는 데 도움이 될 수 있습니다.

나머지는 팀의 답변에 동의해야합니다.


답변

node.js 프로젝트에서 사용할 수있는 named-regexp라는 node.js 라이브러리가 있습니다 (브라우저에서 browserify 또는 기타 패키징 스크립트로 라이브러리를 패키징하여 브라우저에서). 그러나 명명되지 않은 캡처 그룹이 포함 된 정규식에는 라이브러리를 사용할 수 없습니다.

정규식에서 오프닝 캡처 중괄호를 세면 정규 표현식에서 명명 된 캡처 그룹과 번호가 매겨진 캡처 그룹 사이에 매핑을 만들고 자유롭게 혼합하고 일치시킬 수 있습니다. 정규식을 사용하기 전에 그룹 이름을 제거하면됩니다. 나는 그것을 보여주는 세 가지 기능을 작성했습니다. 이 요지를 참조하십시오 : https://gist.github.com/gbirke/2cc2370135b665eee3ef