자바스크립트 정규 표현식
모질라 MDN
https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Regular_Expressions
# 정규 표현식은 두 가지 방법으로 만들 수 있습니다.
1. 정규 표현식 리터럴 이용. (슬래시로 감싸서 작성)
const re = /ab+c/;
2. RegExp 객체의 생성자 이용
const re = new RegExp(‘ab+c’);
- exec()
- test()
- match()
- matchAll()
1. exec()
- lastIndex 값을 기준으로 검색해 나감
- 호출할 때마다 찾은 값에 대한 배열을 반환
- 찾지 못하면 null 반환
const regex1 = RegExp('foo*', 'g');
const str1 = 'table football, foosball';
let array1;
array1 = regex1.exec(str1); // array1[0] : foo, lastIndex : 9
array1 = regex1.exec(str1); // array1[0] : foo, lastIndex : 19
array1 = regex1.exec(str1); // null
// 대소문자 무시, 글로벌, 인덱스 플래그
let re = /quick\s(brown).+?(jumps)/igd;
let result = re.exec('The Quick Brown Fox Jumps Over The Lazy Dog');
// 결과
0: "Quick Brown Fox Jumps"
1: "Brown"
2: "Jumps"
groups: undefined
index: 4 // 4번째 index 부터 일치 시작
indices: (3) [Array(2), Array(2), Array(2), groups: undefined] // 인덱스 플래그
input: "The Quick Brown Fox Jumps Over The Lazy Dog"
length: 3
// 정규 표현식 리터럴 사용
let matches = /(hello \S+)/.exec('This is a hello world!');
console.log(matches[1]);
// 결과
hello world!
2. test()
const str = 'table football';
const regex = new RegExp('foo*');
const globalRegex = new RegExp('foo*', 'g');
regex.test(str); // true
globalRegex.lastIndex; // 0
globalRegex.test(str); //true
globalRegex.lastIndex; // 9
globalRegex.test(str); // false
// 시작 문자 테스트
const str = 'hello world!';
const result = /^hello/.test(str);
console.log(result); // true
// 테스트 성공 여부에 따른 로그 메시지
function testInput(re, str) {
let midstring;
if (re.test(str)) {
midstring = 'contains';
} else {
midstring = 'does not contain';
}
console.log(`${str} ${midstring} ${re.source}`);
}
// global 플래그 설정
const regex = /foo/g; // the "global" flag is set
// regex.lastIndex is at 0
regex.test('foo') // true
// regex.lastIndex is now at 3
regex.test('foo') // false
// regex.lastIndex is at 0
regex.test('barfoo') // true
// regex.lastIndex is at 6
regex.test('foobar') //false
// regex.lastIndex is at 0
// (...and so on)
3. match()
리턴값
– 배열
g 플래그가 있으면 모든 결과를 반환하지만 캡처링 그룹은 포함하지 않습니다.
g 플래그가 없으면 첫번째 결과와 관련 캡처링 그룹을 반환합니다.
설명
1. 확인만 하려면 test()
2. 첫번째 일치만 찾으려면 exec()
3. 캡처링 그룹과 g플래그를 함께 사용하려면 exec() 또는 matchAll() 을 사용하라.
In the following example, match() is used to find “Chapter” followed by one or more numeric
characters followed by a decimal point and numeric character zero or more times.
# match() 사용 예제
const str = 'For more information, see Chapter 3.4.5.1'; const re = /see (chapter \d+(\.\d)*)/i; const found = str.match(re); console.log(found); // logs [ 'see Chapter 3.4.5.1', // 'Chapter 3.4.5.1', // '.1', // index: 22, // input: 'For more information, see Chapter 3.4.5.1' ] // 'see Chapter 3.4.5.1' is the whole match. // 'Chapter 3.4.5.1' was captured by '(chapter \d+(\.\d)*)'. // '.1' was the last value captured by '(\.\d)'. // The 'index' property (22) is the zero-based index of the whole match. // The 'input' property is the original string that was parsed.
# match() 함수와 g 플래그와 i 플래그와 함께 사용
const str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; const regexp = /[A-E]/gi; const matches = str.match(regexp); console.log(matches); // ['A', 'B', 'C', 'D', 'E', 'a', 'b', 'c', 'd', 'e']
# 네임드 캡처링 그룹
const paragraph = 'The quick brown fox jumps over the lazy dog. It barked.';
const capturingRegex = /(?<animal>fox|cat) jumps over/;
const found = paragraph.match(capturingRegex);
console.log(found.groups); // {animal: "fox"}
# 파라미터 없는 match()
– 빈 배열 리턴
const str = "Nothing will come of nothing."; str.match(); // returns [""]
# 파라미터로 non-RegExp 받으면
– new RegExp(regexp) 로 변환됨
const str1 = "NaN means not a number. Infinity contains -Infinity and +Infinity in JavaScript.";
const str2 = "My grandfather is 65 years old and My grandmother is 63 years old.";
const str3 = "The contract was declared null and void.";
str1.match("number"); // "number" is a string. returns ["number"]
str1.match(NaN); // the type of NaN is the number. returns ["NaN"]
str1.match(Infinity); // the type of Infinity is the number. returns ["Infinity"]
str1.match(+Infinity); // returns ["Infinity"]
str1.match(-Infinity); // returns ["-Infinity"]
str2.match(65); // returns ["65"]
str2.match(+65); // A number with a positive sign. returns ["65"]
str3.match(null); // returns ["null"]
# 모든 문자를 의미하는 특수 문자. 점(.)
– 점(.) 을 일반 문자로 사용하려면 이스케이프해서 사용하라.
console.log("123".match("1.3")); // [ "123" ]
->
console.log("123".match("1\\.3")); // null
4. matchAll()
# 리턴값
iterable iterator
# 예외
파라미터가 RegExp 객체인데 g 플래그가 없으면 TypeError 예외 발생
# matchAll() 함수가 없다면 exec() 함수 사용
const regexp = /foo[a-z]*/g;
const str = 'table football, foosball';
let match;
while ((match = regexp.exec(str)) !== null) {
console.log(`Found ${match[0]} start=${match.index} end=${regexp.lastIndex}.`);
// expected output: "Found football start=6 end=14."
// expected output: "Found foosball start=16 end=24."
}
# matchAll() 를 사용하면 exec() 함수와 while 루프 사용을 피할 수 있다.
– for…of 또는 array spread 또는 Array.from() 사용 가능
const regexp = /foo[a-z]*/g;
const str = 'table football, foosball';
const matches = str.matchAll(regexp);
for (const match of matches) {
console.log(`Found ${match[0]} start=${match.index} end=${match.index + match[0].length}.`);
}
// expected output: "Found football start=6 end=14."
// expected output: "Found foosball start=16 end=24."
// matches iterator is exhausted after the for..of iteration
// Call matchAll again to create a new iterator
Array.from(str.matchAll(regexp), (m) => m[0]);
// Array [ "football", "foosball" ]
# g 플래그가 없으면 예외 발생
const regexp = /[a-c]/; const str = 'abc'; str.matchAll(regexp); // TypeError
# lastIndex() 는 사용되지 않는다.
const regexp = /[a-c]/g;
regexp.lastIndex = 1;
const str = 'abc';
Array.from(str.matchAll(regexp), (m) => `${regexp.lastIndex} ${m[0]}`);
// Array [ "1 b", "1 c" ]
# 캡처 그룹에 더 나은 접근
– match() 는 g 플래그와 같이 사용하면 캡처 그룹은 무시된다.
const regexp = /t(e)(st(\d?))/g; const str = 'test1test2'; str.match(regexp); // Array ['test1', 'test2']
# matchAll() 로 캡처 그룹에 더 쉽게 접근 할 수 있다.
const array = [...str.matchAll(regexp)]; array[0]; // ['test1', 'e', 'st1', '1', index: 0, input: 'test1test2', length: 4] array[1]; // ['test2', 'e', 'st2', '2', index: 5, input: 'test1test2', length: 4]