문자열에서 정규표현식과 매치되는 부분을 검색한다.
const paragraph = 'Cats are the best';
const regex = /[A-Z]/g;
const found = paragraph.match(regex);
found; // ["C"]
정규식과 매치해서 그 값이 있음 배열로 반환하는거 아닌가? 하고 생각할 수 있는데 match()의 반환값이 다양하기 때문에 간단하게 넘어갈 수 없다.
g
플래그에 따른 결과 Array
를 반환, 매치되는 결과가 없다면 null
를 반환한다.
정규식엔 6가지의 플래그를 사용할 수 있는데 위 예시에서 /[A-Z]/g
마지막에 붙은 g
가 플래그이다.
g
플래그는 전역 플래그로 전체 일치하는 모든 결과
를 반환한다.
match() 메서드는 g
플래그 유무에 따라 캡쳐 그룹(Capture Group)
유무에 영향을 끼쳐 반환값이 달라진다.
g
플래그를 사용하고 있다면 정규 표현식과 일치하는 모든 결과를 Array형으로 반환하지만, 캡쳐그룹은 반환하지 않는다.
const str = "Cats are the best. The cat will rule the universe.";
const regexpWithoutE = /\b[a-df-z]+\b/ig;
str.match(regexpWithoutE); // ["Cats", "cat", "will"]
캡쳐그룹이 반환값에 포함되지 않았으며 일치하는 요소가 모두
반환된것을 확인 할 수 있다.
(i 플래그를 사용하면 대소문자를 구분하지 않는다)
g
플래그를 사용하지 않았다면 처음 일치한 값과 캡쳐 그룹을 같이 Array형으로 반환한다.
const str = "Cats are the best. The cat will rule the universe.";
const regexpWithoutE = /\b[a-df-z]+\b/i;
str.match(regexpWithoutE);
// ["Cats", index: 0, input: "Cats are the best. The cat will rule the universe.", groups: undefined]
g
플래그를 뺐을뿐인데 index
, input
, groups
3개의 프로퍼티가 생겼고,
처음 일치한 값만 배열에 요소로 반환되었다.
반환값이 null
이 아니거나, g
flag를 사용하지 않을 경우 결과값에 추가 프로퍼티가 붙는다.
몇 번째 index에서 매치된 문자열이 나오는지를 나타내는 index
와 입력된 원래 문자열을 나타내는 input
그리고 마지막으로 groups
이다.
캡쳐 그룹은 괄호를 둘러싼 영역
을 말한다.
(?<Name>x)
x에 매치되면 명명된 이름<name>
이 key가 되고, 정규식 x에 일치되는 값이 value가 된다.
캡쳐 그룹을 사용하면 패턴 안의 원하는 부분을 편리하게 사용할 수 있다.
let re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u;
const result = '2015-01-02'.match(re);
result;
/*
[
"2015-01-02", "2015", "01", "02"
groups: {year: "2015", month: "01", day: "02"},
index: 0,
input: "2015-01-02",
length: 4
]
*/
(?<year>\d{4})
괄호를 둘러싼 영역임을 확인할 수 있으며 (?<Name>x)
과 동일하게 사용되었다.
groups: {year: "2015", month: "01", day: "02"}
<Name>
인 year
가 key가 되고 정규식과 매치되는 부분
이 value가 되었다.
result.groups; // {year: "2015", month: "01", day: "02"}
result.groups.year; // "2015"
result.groups.month; // "01"
result.groups.day; // "02"
이렇게 특정부분에 접근할 수 있다.
캡쳐그룹을 포함하여 정규식에 대한 문자열과 일치하는 모든 결과의 반복자(iterator) object가 반환한다.
let regexp = /고(양)(이(\d?))/g;
let str = '고양이1고양이2';
let array = [...str.matchAll(regexp)];
array[0]; // ["고양이1", "양", "이1", "1", index: 0, input: "고양이1고양이2", groups: undefined]
array[1]; // ["고양이2", "양", "이2", "2", index: 4, input: "고양이1고양이2", groups: undefined]
RegExp
객체는 무조건 /g
플래그를 가져야 하며, 아니면 TypeError
를 던진다. 반환값인 반복자는 재시작 반복이 불가능하다.
const regexp = /고(양)(이(\d?))/g;
const str = '고양이1고양이2';
const matches = str.matchAll(regexp);
for (const match of matches) {
console.log(`찾았다 ${match[0]} start=${match.index} end=${match.index + match[0].length}.`);
}
// 찾았다 고양이1 start=0 end=4.
// 찾았다 고양이2 start=4 end=8.
// 재시작 반복이 불가능하다.
// 새로운 반복자를 만들어 matchAll을 다시 호출해야한다.
Array.from(str.matchAll(regexp), m => m[0]);
// ["고양이1", "고양이2"]
matchAll
은 g
플래그가 없다면 TypeError가 발생한다.const regexp = RegExp('[a-c]', '');
const str = 'abc';
str.matchAll(regexp); // TypeError
match()메서드와 g
플래그를 같이 사용했을 경우
let re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/g;
const result = '2015-01-02,2015-01-03'.match(re);
result;
// ["2015-01-02", "2015-01-03"]
매치되는 전체를 얻을 순 있지만, index
, input
, groups
3개의 프로퍼티는 사용할 수 없다.
matchAll()메서드
let re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/g;
const result = '2015-01-02,2015-01-03'.matchAll(re);
let array = [...result];
array[0];
/*
[
"2015-01-02" // 완전히 매치
"2015" // '(?<year>\d{4})' 부분에 의해 매치
"01" // '(?<month>\d{2})' 부분에 의해 매치
"02" // '(?<day>\d{2})' 부분에 의해 매치
groups: {year: "2015", month: "01", day: "02"}
index: 0
input: "2015-01-02,2015-01-03"
]
*/
match()와 다르게 index
, input
, groups
3개의 프로퍼티를 사용할 수 있는걸 확인할 수 있다.
g
플래그를 사용하지 않고 매치되는 값이 있는경우 단 한개만 배열로 반환된다. index
, input
, groups
3개의 프로퍼티와 같이 사용할 수 있다.g
플래그를 사용했을 경우 모든 매치된 값을 배열로 반환된다. index
, input
, groups
3개의 프로퍼티와 같이 사용할 수 없다.괄호를 둘러싼 영역
을 말한다. (?<Name>x)
캡쳐 그룹을 사용하면 패턴 안의 원하는 부분을 편리하게 사용할 수 있다.g
플래그와 캡쳐그룹을 같이 사용할 수 없는 점이 보완되었다. g
플래그가 없다면 TypeError가 발생한다.참고