JavaScript 정규식에서 캡처 그룹을 지정 했습니까?
내가 아는 한 JavaScript에는 캡쳐 그룹이라는 것과 같은 것이 없습니다. 유사한 기능을 얻는 다른 방법은 무엇입니까?
ECMAScript 2018은 명명 된 캡처 그룹 을 JavaScript 정규식에 도입 합니다.
구형 브라우저를 지원해야하는 경우 명명 된 캡처 그룹으로 수행 할 수있는 일반 (번호가 매겨진) 캡처 그룹으로 모든 작업을 수행 할 수 있습니다. 숫자 만 추적하면됩니다. 그룹을 캡처하는 순서가 정규식 변경.
내가 생각할 수있는 명명 된 캡처 그룹의 두 가지 "구조적"장점은 다음과 같습니다.
일부 정규식 맛 (.NET 및 JGSoft, 내가 아는 한)에서는 정규식의 다른 그룹에 동일한 이름을 사용할 수 있습니다 ( 여기에서 중요한 예는 여기 참조 ). 그러나 대부분의 정규 표현식은이 기능을 지원하지 않습니다.
숫자로 둘러싸인 상황에서 번호가 매겨진 캡처 그룹을 참조해야하는 경우 문제가 발생할 수 있습니다. 하자 당신이 자리에 0을 추가 할 따라서 교체 할 말
(\d)
과 함께$10
. 자바 스크립트,이 의지 (당신이 당신의 정규식에서 10 개 미만의 캡처 그룹을 가지고 같은) 작동하지만 펄은 역 참조 번호를 찾고 있다고 생각합니다10
대신 숫자의1
다음에0
. Perl에서는${1}0
이 경우에 사용할 수 있습니다 .
그 외에, 명명 된 포획 그룹은 단지 "구문 설탕"이다. 캡처 그룹은 실제로 필요할 때만 사용 (?:...)
하고 다른 모든 상황에서는 캡처되지 않은 그룹을 사용하는 데 도움이됩니다 .
JavaScript의 더 큰 문제는 (제 생각에) 읽기 쉬운 복잡한 정규 표현식을 훨씬 쉽게 만들 수있는 자세한 정규 표현식을 지원하지 않는다는 것입니다.
Steve Levithan의 XRegExp 라이브러리 는 이러한 문제를 해결합니다.
추가 구문, 플래그 및 메소드에 대한 지원을 포함하여 정규 표현식의 확장되고 확장 가능한 크로스 브라우저 구현 인 XRegExp 를 사용할 수 있습니다 .
- 명명 된 캡처에 대한 포괄적 인 지원을 포함하여 새로운 정규식 및 대체 텍스트 구문을 추가합니다 .
s
점을 모든 문자 (일명 dotall 또는 단일 행 모드)와 일치시키고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';
캡처 된 그룹의 이름을 지정하면 복잡한 정규식과의 혼동이 줄어 듭니다.
실제로 사용 사례에 따라 다르지만 정규식을 인쇄하면 도움이 될 수 있습니다.
또는 캡처 된 그룹을 참조하기 위해 상수를 시도하고 정의 할 수 있습니다.
그런 다음 주석은 코드를 읽는 다른 사람에게 수행 한 작업을 보여줄 수도 있습니다.
나머지는 팀의 답변에 동의해야합니다.
There is a node.js library called named-regexp that you could use in your node.js projects (on in the browser by packaging the library with browserify or other packaging scripts). However, the library cannot be used with regular expressions that contain non-named capturing groups.
If you count the opening capturing braces in your regular expression you can create a mapping between named capturing groups and the numbered capturing groups in your regex and can mix and match freely. You just have to remove the group names before using the regex. I've written three functions that demonstrate that. See this gist: https://gist.github.com/gbirke/2cc2370135b665eee3ef
While you can't do this with vanilla JavaScript, maybe you can use some Array.prototype
function like Array.prototype.reduce
to turn indexed matches into named ones using some magic.
Obviously, the following solution will need that matches occur in order:
// @text Contains the text to match
// @regex A regular expression object (f.e. /.+/)
// @matchNames An array of literal strings where each item
// is the name of each group
function namedRegexMatch(text, regex, matchNames) {
var matches = regex.exec(text);
return matches.reduce(function(result, match, index) {
if (index > 0)
// This substraction is required because we count
// match indexes from 1, because 0 is the entire matched string
result[matchNames[index - 1]] = match;
return result;
}, {});
}
var myString = "Hello Alex, I am John";
var namedMatches = namedRegexMatch(
myString,
/Hello ([a-z]+), I am ([a-z]+)/i,
["firstPersonName", "secondPersonName"]
);
alert(JSON.stringify(namedMatches));
As Tim Pietzcker said ECMAScript 2018 introduces named capturing groups into JavaScript regexes. But what I did not find in the above answers was how to use the named captured group in the regex itself.
you can use named captured group with this syntax: \k<name>
. for example
var regexObj = /(?<year>\d{4})-(?<day>\d{2})-(?<month>\d{2}) year is \k<year>/
and as Forivin said you can use captured group in object result as follow:
let result = regexObj.exec('2019-28-06 year is 2019');
// result.groups.year === '2019';
// result.groups.month === '06';
// result.groups.day === '28';
var regexObj = /(?<year>\d{4})-(?<day>\d{2})-(?<month>\d{2}) year is \k<year>/mgi;
function check(){
var inp = document.getElementById("tinput").value;
let result = regexObj.exec(inp);
document.getElementById("year").innerHTML = result.groups.year;
document.getElementById("month").innerHTML = result.groups.month;
document.getElementById("day").innerHTML = result.groups.day;
}
td, th{
border: solid 2px #ccc;
}
<input id="tinput" type="text" value="2019-28-06 year is 2019"/>
<br/>
<br/>
<span>Pattern: "(?<year>\d{4})-(?<day>\d{2})-(?<month>\d{2}) year is \k<year>";
<br/>
<br/>
<button onclick="check()">Check!</button>
<br/>
<br/>
<table>
<thead>
<tr>
<th>
<span>Year</span>
</th>
<th>
<span>Month</span>
</th>
<th>
<span>Day</span>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<span id="year"></span>
</td>
<td>
<span id="month"></span>
</td>
<td>
<span id="day"></span>
</td>
</tr>
</tbody>
</table>
참고URL : https://stackoverflow.com/questions/5367369/named-capturing-groups-in-javascript-regex
'Programming' 카테고리의 다른 글
“mvn clean install”과“mvn install”의 차이점은 무엇입니까? (0) | 2020.05.16 |
---|---|
Python 2.x와 함께 Python 3.x에서 pip를 사용하는 방법 (0) | 2020.05.16 |
AndroidX 란 무엇입니까 (0) | 2020.05.16 |
값없이 속성 설정 (0) | 2020.05.16 |
Objective-C에서 Java의 "instanceof"키워드와 동등한 것은 무엇입니까? (0) | 2020.05.16 |