개발을 하며 특정 문자를 바꾸거나 문자열이 유효성을 검사하거나, 개발자가 제한한 검사기준을 통과했는지 등을 검사, 평가 교환할 때 정규 표현식을 사용하면 편리합니다.
정규 표현식(regular expression)이란 특정한 규칙을 가진 문자열의 집합을 표현하는데 사용하는 형식언어로써 패턴을 사용해 문자열의 검색과 치환을 돕습니다.
RegExp 오브젝트란 JS에서 지원하는 오브젝트로써 패턴을 사용해 텍스트를 판별할 때 사용합니다. 이 오브젝트는 리터럴 표기법과 생성자로써 생성할 수 있는데,
/ab+c/i new RegExp(/ab+c/, 'i'); // 리터럴 new RegExp('ab+c', 'i'); // 생성자
- 리터럴 표기법의 매개변수는 두 빗금으로 감싸야 하며 따옴표를 사용하지 않습니다.
- 생성자 함수의 매개변수는 빗금으로 감싸지 않으나 따옴표를 사용합니다.
lastIndex는 RegExp 오브젝트의 내부 프로퍼티 중 하나로써 매치 시작 위치를 설정합니다. 기본값은 0으로 플래그에 따라서 사용 여부가 결정됩니다.
const value = "ABC"; const obj = new RegExp("A", "g"); console.log(obj.test(value)); const reg = /A/g; console.log(reg.test(value)); // true // true
const value = "ABABA", obj = /B/g; console.log(obj.test(value) +": "+obj.lastIndex); console.log(obj.test(value) +": "+obj.lastIndex); console.log(obj.test(value) +": "+obj.lastIndex); // true: 2 // true: 4 // false: 0
const value = "ABABA", obj = /B/; console.log(obj.test(value) +": "+obj.lastIndex); obj.lastIndex = 2; console.log(obj.test(value) +": "+obj.lastIndex); console.log(obj.test(value) +": "+obj.lastIndex); // true: 0 // true: 2 // true: 2
RegExp 오브젝트에서는 플래그를 어떻게 설정하느냐에 따라 같은 문자열과 같은 정규식을 쓰더라도 다른 결과값을 볼 수 있습니다.
g플래그를 사용하면 lastIndex가 업데이트되며 전체 순회를하면서 문자열 검색&치환을 할 수 있습니다. 플래그가 없을경우 매번 처음부터 매치를 합니다.
y플래그는 또한, lastIndex를 사용하지만, g플래그와는 다릅니다. g플래그가 lastIndex부터 매치를 한다면, y플래그는 lastIndex위치를 매치합니다.
즉, g플래그가 lastIndex의 위치부터 끝까지 문자열을 하나씩 매치를 한 다음 매치가 없을 경우 lastIndex를 0으로 하고 매치가 있을 경우 해당 위치 +1을 lastIndex로 한다면
y플래그는 lastIndex위치에 매치를 하고 매치가 될 경우에만 +1을 하고 아니면 그 뒤를 순회하는게 아닌 바로 lastIndex에 0을 설정합니다.
const value = "AABBA", obj = /A/y console.log(obj.test(value) + ": "+ obj.lastIndex); console.log(obj.test(value) + ": "+ obj.lastIndex); console.log(obj.test(value) + ": "+ obj.lastIndex); // true: 1 // true: 2 // false: 0
문자열 value를 보면 마지막 문자가 A입니다. 하지만, 중간의 B를 만나 매치 결과가 false가 되면 lastIndex는 0이되기 때문에 마지막 문자를 매치할 수 없습니다. 이를 통해 연속된 문자 패턴을 검증하는 경우에 y플래그는 유용하게 사용됩니다.
const value = "AABBA", obj = /A/y if(obj.sticky) obj.lastIndex = 4; console.log(obj.test(value) + ": "+ obj.lastIndex); // true: 5
u플래그는 정규 표현식의 패턴을 유니코드의 코드 포인트로 변환하여 매치합니다. 더하여 내부 프로퍼티 중 unicode 프로퍼티가 true로 설정됩니다. 만일 u플래그를 사용하지 않는다면 코드포인트를 변환하지 않고 문자로 매치합니다.
const obj = new RegExp("\u{31}\u{32}", "u"); const obj2 = new RegExp(String.raw `\u{31}\u{32}`) console.log(obj.test("12")); //true console.log(obj.unicode); //true console.log(obj2.test("12")); //false console.log(obj2.unicode); //false console.log(/\u{1f418}/u.test("🐘")); //true console.log(/\u{1f418}/.test("🐘")); //false
✔ ES2018 부터 지원
기존에 정규 표현식에서 dot(점.)은 모든 문자를 매치하지만 줄 바꿈 문자는 매치하지 않았습니다. 하지만 ES2018부터 지원되는 S플래그를 사용하면 줄 바꿈 문자도 매치를 하고, 내부 프로퍼티인 dotAll 프로퍼티에 true로 설정됩니다.
const text = `line 줄을 바꿈`; // before console.log(/[\s\S]+/.test(text)); console.log(/[^]+/.test(text)); // true // true // s flag const obj = new RegExp(".+", "s"); console.log(obj.test(text)); console.log(obj.dotAll); // true // true