목차
정규 표현식
- 형식 언어(formal language)
- 정규 표현식은 문자열의 특정 문자 조합과 대응시키기 위해 사용되는 패턴이다.
- 대부분 프로그래밍 언어와 코드 에디터에 내장
- 패턴 매칭 기능 제공: 특정 패턴과 일치하는 문자열을 검색 or 추출 or 치환
- 정규식은 주석이나 공백을 허용하지 않는다.
- 여러가지 기호를 혼합하여 사용하여 가독성이 좋지않다.
패턴(표현식)과 플래그로 구성
- 패턴은 문자열의 일정한 규칙을 표현한다.
- 패턴은 메타문자 또는 기호로 표현할 수 있다.
- 패턴과 일치하는 문자열이 존재할 때 ‘정규식과 매치한다’라고 한다.
- 패턴은 “/”로 감싸 표현한다.
- 플래그는 정규 표현식의 검색 방식을 설정하기 위해 사용한다.
예시
- 아래와 같이 반복문 없이 패턴을 정의하고 테스트할 수 있다.
1
2
3
const tel = "010-1234-오오칠칠";
const regex = /^\d{3}-\d{4}-\d{4}$/; // -> 숫자3개, 숫자4개, 숫자 4개 라는 패턴
regex.test(tel); // -> false
플래그
플래그 | 의미 | 설명 |
---|---|---|
i | Ignore case | 대소문자 구별 x 패턴 검색 |
g | Global | 패턴과 일치하는 모든 문자열 전역 검색 |
m | Multi line | 다중행 검색 |
s | .에 개행 문자도 매칭 | |
u | Unicode | 패턴을 유니코드 포인트의 나열로 취급한다 |
y | Sticky | 문자열의 현재 위치부터 검색을 수행한다 |
- 플래그 == 옵션
- 선택적 사용가능하다.
- 순서와 상관없이 하나 이상의 플래그 동시 사용가능하다.
- 어떠한 플래그를 사용하지 않은 경우 대소문자 구별하고, 첫 매칭한 대상만 검색하고 종료한다.
- ‘m’ 플래그는 입력 문자열을 여러 줄로 다루기 위해 사용한다. 이 때 ‘^’, ‘$’ 는 전체 문자열의 첫과 끝을 나타내는것이 아니라 각 줄의 첫과 끝을 나타낸다.
정규식 생성
- 정규표현식 리터럴 or RegExp 생성자 함수를 사용하여 생성
정규식 리터럴을 사용하는 방법
- 슬래시 “/”로 감싸는 패턴 + 플래그(flag)
1
2
3
4
var re = /ab+c/;
const target = "is this all there is?";
const regex = /is/i; // i 플래그 : 대소문자 구별 x 검색
regex.test(target); // -> true
- 정규식 리터럴은 스크립트가 불러와질 때 컴파일된다.(정규식이 상수라면 성능 향상)
생성자 함수 호출 방법
1
2
3
4
5
6
7
8
9
10
11
/**
* pattern: 정규 표현식의 패턴
* flags: 정규 표현식의 플래그(g, i, m, u, y)
*/
new RegExp(pattern[, flags])
var re = new RegExp("ab+c");
const target = 'is this all there is?';
const regex = new RegExp(/is/i); //ES6
//const regex = new RegExp(/is/,'i');
//const regex = new RegExp('is','i');
regex.test(target); // -> true
- 실행 시점에 컴파일된다.
- 패턴이 변경될 수 있는 경우 사용한다.
- 사용자 입력과 같이 다른 곳에서 패턴을 가져올 때 사용한다.
RegExp 메서드
RegExp.prototype.exec
- 인수로 전달받은 문자열에 대해 정규식의 패턴을 검색, 매칭 결과를 배열로 반환한다.
- 매칭 결과가 없는 경우 null
- 문자열 내의 모든 패턴을 검색하는 g 플래그를 지정해도 첫 매칭 결과만 반환한다.
1
2
3
4
5
const target = "Is this is";
const regex = /is/;
regex.exec(target);
//-> (1) ['is', index: 5, input: 'Is this is', groups: undefined]
- ‘g’ 플래그를 사용하면, 진행상황에 대한 정보가 반환된다.
1
2
3
4
5
6
7
var xArray;
var str = "fee fi fo fum";
var re = /\w+\s/g;
while ((xArray = re.exec(str))) console.log(xArray);
// ["fee ", index: 0, input: "fee fi fo fum"]
// ["fi ", index: 4, input: "fee fi fo fum"]
// ["fo ", index: 7, input: "fee fi fo fum"]
RegExp.prototype.test
- 매칭결과를 불리언 값으로 반환한다.
1
2
3
4
5
const target = "Is this is";
const regex = /is/;
regex.test(target);
//-> true
String.prototype.match
- String 표준 빌트인 객체가 제공하는 메서드
- 매칭결과를 배열로 반환한다.
- exec 메서드와는 다르게 g 플래그로 모든 매칭 결과를 반환한다.
1
2
3
4
5
6
7
8
const target = "Is this is";
const regex = /is/g;
const regex1 = /is/;
target.match(regex);
//-> (2) ['is', 'is']
target.match(regex1);
//-> (1) ['is', index: 5, input: 'Is this is', groups: undefined]
String.prototype.search
- 대응되는 문자열이 있는지 검사한다.
- 대응된 부분의 인덱스를 반환한다.
- 문자열을 찾지 못하면 -1을 반환한다.
String.prototype.replace
- 대응되는 문자열을 찾아 다른 문자열로 치환한다.
- 아래는 특수문자 제거 예제이다.
target.replace(/[^A-Za-z0-9]/gi, '')
String.prototype.split
- 정규식 혹은 문자열로 대상 문자열을 나누어 배열로 반환한다.
예제들
문자열 검색
대소문자 구별
1
2
3
4
5
const target = "Is this is";
const regex = /is/;
regex.test(target); //-> true
target.match(regex); //-> (1) ['is', index: 5, input: 'Is this is', groups: undefined]
대소문자 구별 x
1
2
3
4
const target = "Is this is";
const regex = /is/i;
target.match(regex); //-> (1) ['Is', index: 0, input: 'Is this is', groups: undefined]
모든 문자열 전역 검색
1
2
3
4
const target = "Is this is";
const regex = /is/gi;
target.match(regex); //-> (3) ['Is',"is", "is]
임의의 문자열 검색
- .은 임의의 문자 한 개를 의미한다.
- 아래는 문자의 내용과 상관없이 3자리 문자열과 매치한다.
1
2
3
4
5
const target = "Is this is";
// 임의의 3자리 문자열을 대소문자를 구별하여 전역 검색한다.
const regex = /.../g;
target.match(regex); //-> (3) ['Is ', 'thi', 's i']
반복 검색
/A{m,n}/
- {m, n}은 앞 패턴이 최소 m번, 최대 n번 반복되는 문자열을 의미한다.
- 콤마 뒤에 공백이 있으면 정상 동작하지 않는다.
- m <= n, 양의 정수
- n이 생략되면 ∞ 취급
1
2
3
4
const target = "A AA B BB Aa Bb AAA";
const regex = /A{1,2}/g;
target.match(regex); //-> (5) ['A', 'AA', 'A', 'AA', 'A']
- {n}은 앞 패턴이 n번 반복되는 문자열을 의미한다.
- {n} == {n, n}
1
2
3
4
const target = "A AA B BB Aa Bb AAA";
const regex = /A{2}/g;
target.match(regex); //-> (2) ['AA', 'AA']
- {n,}은 앞 패턴이 최소 n번 이상 반복되는 문자열을 의미한다.
1
2
3
4
const target = "A AA B BB Aa Bb AAA";
const regex = /A{2,}/g;
target.match(regex); //-> (2) ['AA', 'AAA']
/A+/
+는 앞 패턴이 최소 한번 이상 반복되는 문자열을 의미한다.
+ == {1,}
1
2
3
4
const target = "A AA B BB Aa Bb AAA";
const regex = /A+/g;
target.match(regex); //-> (2) ['A', 'AA', 'A','AAA']
/A?/
- ?는 앞 패턴이 0 또는 1회 등장하는 부분과 대응된다.
- ? == {0,1}
- 수량자 *, +, ?, {} 바로뒤에 사용하여 가능한 많이 대응시키지 않기위해 사용한다. (ex. A{1,3}일경우 AAA가 대응되지만, A{1,3}? 의 경우 A 만 대응됨)
- 사전 검증을 위해서도 사용한다.
1
2
3
4
const target = "color colour colouur colouuur colou colo our";
const regex = /colou?r/g;
target.match(regex); //-> (2) ['color', 'colour']
OR 검색
A|B
- | 은 or의 의미한다.
1
2
3
4
5
const target = "A AA B BB Aa Bb AAA";
const regex = /A|B/g;
target.match(regex);
//-> (11) ['A', 'A', 'A', 'B', 'B', 'B', 'A', 'B', 'A', 'A', 'A']
- +를 붙여 분해하지 않을 수 있다.
1
2
3
4
5
const target = "A AA B BB Aa Bb AAA";
const regex = /A+|B+/g;
target.match(regex);
//-> (7) ['A', 'AA', 'B', 'BB', 'A', 'B', 'AAA']
[A]
- [] 내의 문자는 or로 동작한다.
- /[AB]/+/g == /A+|B+/g
- [] 내에 -를 사용하면 범위를 지정할 수 있다.
- /[A-Z]+/g
1
2
3
4
5
6
const target = "A AA AaA B aa Bb aB 1 2";
const regex = /[A-Z]+/g;
// regex = /[A-Z]+/gi; // (7) ['A', 'AA', 'AaA', 'B', 'aa', 'Bb', 'aB']
// regex = /[A-Za-z]+/g; // (7) ['A', 'AA', 'AaA', 'B', 'aa', 'Bb', 'aB']
// regex = /[0-9]+/g; // (2) ['1', '2']
target.match(regex); // (7) ['A', 'AA', 'A', 'A', 'B', 'B', 'B']
- 숫자의 경우 쉼표(“,”)가 붙으면 매칭 결과가 분리되므로 패턴에 넣어줘야한다.
1
2
3
4
const target = "A AA 12,345";
// const regex = /[0-9,]/g; // (2) ['12', '345']
const regex = /[0-9,]+/g;
target.match(regex); // (1) ['12,345']
- [0-9] == [\d]
- [\D] == [\d]가 아닌 것
- [\w] == 알파벳, 숫자, 언더 스코어 == [A-za-z0-9_]
- [\W] == [\w] 가 아닌것
- [\s] == 여러가지 공백문자등을 의미한다
- [\s] == [\t\r\n\v\f]
NOT 검색
- […] 내의 ^은 not 이다.
- [^\d] == [\D]
시작 위치 검색
- […] 밖의 ^은 문자열의 시작을 의미한다.
- 단, […] 내의 ^은 not의 의미를 가진다.
1
2
3
const target = "https://";
const regex = /^https/; // http 로 시작하는지 검사
target.match(regex); // true
마지막 위치 검색
- $은 문자열의 마지막을 의미한다
1
2
3
const target = "https:// .com";
const regex = /com$/; // com으로 끝나는지 검사
target.match(regex); // true
괄호로 둘러싼 패턴 사용
- 괄호는 해당 부분에 대응된 문자열을 기억한다.
- 기억된 문자열은 이후 다른 곳에서 사용한다.
1
2
3
4
5
6
var re = /(\w+)\s(\w+)/;
var str = "John Smith";
var newstr = str.replace(re, "$2, $1");
console.log(newstr);
// "Smith, John"
레퍼런스
- 모던 자바스크립트 Deep Dive 578p~
- mozilla-Regular_Expressions