writed by johan
정규 표현식(Regular Expression, 줄여서 Regex 또는 Regexp)은 문자열에서 패턴을 찾거나 조작하기 위해 사용되는 형식 언어이다. 정규 표현식은 문자열 검색, 대체, 추출 등 다양한 작업에 유용하며, 다양한 프로그래밍 언어와 텍스트 편집기에서 지원된다. 자바스크립트는 펄(Pearl)의 정규 표현식 문법을 ES3부터 도입했다.
정규 표현식 객체(RegExp 객체)를 생성하기 위해서는 두 가지 방법을 사용할 수 있다.
일반적으로 정규 표현식 리터럴을 사용한다.
정규 표현식 리터럴은 다음과 같이 표현한다.
/regex/i
/: 시작, 종료 기호
regex: 패턴
i: 플래그
대소문자를 구별하지 않고 패턴을 검색한다.
전역 검색을 수행한다. 이 플래그가 없으면 문자열에서 첫 번째 매치만 찾는다.
여러 줄에 걸친 검색을 수행한다. 이 플래그가 설정되면, '^'와 '$' 메타문자는 문자열의 시작과 끝뿐 아니라 각 줄의 시작과 끝에도 일치하게 된다.
문자열 검색: test()
메서드를 사용하여 문자열에 특정 패턴이 있는지 확인할 수 있다.
const regex = /hello/;
const str = 'hello world';
console.log(regex.test(str)); // true
문자열 치환: replace()
메서드를 사용하여 문자열에서 정규표현식에 해당하는 부분을 다른 문자열로 바꿀 수 있다.
const regex = /world/g;
const str = 'hello world, world';
console.log(str.replace(regex, 'JavaScript')); // "hello JavaScript, JavaScript"
문자열 추출: exec()
메서드를 사용하여 문자열에서 정규표현식에 해당하는 부분을 추출할 수 있다.
const regex = /is/g;
const str = 'Is this all there is?';
console.log(regex.exec(str));
// ['is', index: 5, input: 'Is this all there is?', groups: undefined]
exec 메서드는 문자열 내의 모든 패턴을 검색하는 g 플래그를 지정해도 첫 번째 매칭 결과만 반환한다. 하지만 String.prototype.match 메서드는 g 플래그가 지정되면 모든 매칭 결과를 배열로 반환한다.
문자열 추출: match()
메서드를 사용하여 문자열에서 정규표현식에 해당하는 부분을 추출할 수 있다.
const regex = /\\d+/g; // 숫자에 해당하는 부분을 전역적으로 찾는 정규표현식
const str = '123 abc 456 def';
console.log(str.match(regex)); // ["123", "456"]
이처럼 다양한 방법으로 정규 표현식을 활용할 수 있으며, 이 외에도 많은 기능들이 존재한다.
만약 정규 표현식을 사용하지 않는다면 반복문과 조건문을 통해 한 문자씩 연속해서 체크해야 하는 번거로움이 있다.
정규 표현식에서 메타문자(meta-character)란 특별한 의미를 가진 문자를 말한다. 메타문자들은 패턴을 정의할 때 사용되며, 문자열 내에서 특정 위치, 문자 집합, 또는 반복 등을 나타낸다.
[]
는 일치하는 문자들의 집합을 지정하기 위해 사용한다. 대괄호 안에 있는 어떤 문자라도 일치하는 것을 찾는다.
let regex = /[aeiou]/g;
let str = "Hello, how are you?";
let match;
while ((match = regex.exec(str)) !== null) {
console.log(`Found ${match[0]} at position ${match.index}`);
}
위의 코드에서 정규표현식 /[aeiou]/g
는 'a', 'e', 'i', 'o', 'u' 중 어느 것이라도 일치하는 문자를 찾는다. 따라서 "Hello, how are you?" 내의 모든 모음이 매칭된다.
Found e at position 1
Found o at position 4
Found o at position 7
Found a at position 10
Found e at position 12
Found o at position 15
Found u at position 18
.
는 임의의 단일 문자와 일치한다. 즉, 어떤 문자든지와 일치할 수 있다. (단, 줄바꿈 문자 제외).
예를 들어 /a.b/
라는 정규표현식은 'a'와 'b' 사이에 어떤 한 글자가 있는 경우와 매칭된다 (예: "acb", "a$b", "a9b" 등).
^
는 문자열이나 행이 (멀티라인 모드일 경우) 특정 패턴으로 시작하는지 검사할 때 사용된다.
let regex = /^cat/g;
let str1 = "cat is on the mat";
let str2 = "the cat is on the mat";
console.log(regex.test(str1)); // true
console.log(regex.test(str2)); // false
참고로 [ … ] 내의 ^은 not의 의미를 갖는다. 예를 들어, [^0-9]는 숫자를 제외한 문자를 의미한다.
const target = 'AA BB 12 Aa Bb';
// 숫자를 제외한 문자열을 전역 검색한다.
const regExp = /[^0-9]+/g;
target.match(regExp); // ["AA Bb ", " Aa Bb"]
$
는 문자열이나 행이 (멀티라인 모드일 경우) 특정 패턴으로 끝나는지 검사할 때 사용된다.
let regex = /end$/g;
let str1 = "This is the end";
let str2 = "The end is near";
console.log(regex.test(str1)); // true
console.log(regex.test(str2)); // false
*
는 앞선 요소가 0번 이상 반복되는 부분과 일치한다.
let regex = /ca*r/g;
let str = "cr car caar caaar";
let match;
while ((match = regex.exec(str)) !== null) {
console.log(`Found ${match[0]} at position ${match.index}`);
}
위의 코드에서 정규표현식 /ca*r/g
는 'c'로 시작하고 'r'로 끝나며, 그 사이에 'a'가 0번 이상 반복되는 문자열을 찾는다. 따라서 "cr", "car", "caar", "caaar" 등이 모두 매칭된다. 실행 결과는 다음과 같다.
Found cr at position 0
Found car at position 3
Found caar at position 7
Found caaar at position 12
+
는 앞선 요소가 1번 이상 반복되는 부분과 일치한다.
let regex = /ca+r/g;
let str = "cr car caar caaar";
let match;
while ((match = regex.exec(str)) !== null) {
console.log(`Found ${match[0]} at position ${match.index}`);
}
위의 코드에서 정규표현식 /ca+r/g
는 'c'로 시작하고 'r'로 끝나며, 그 사이에 'a'가 1번 이상 반복되는 문자열을 찾는다.
Found car at position 3
Found caar at position 7
Found caaar at position 12
?
는 앞선 요소가 0번 또는 1번 반복되는 부분과 일치한다.
let regex = /ca?r/g;
let str = "cr car caar";
let match;
while ((match = regex.exec(str)) !== null) {
console.log(`Found ${match[0]} at position ${match.index}`);
}
위의 코드에서 정규표현식 /ca?r/g
는 'c'로 시작하고 'r'로 끝나며, 그 사이에 'a'가 없거나 1번 있는 문자열을 찾는다. 따라서 "cr"와 "car"가 매칭된다.
Found cr at position 0
Found car at position 3
\d
, \w
, \s
는 숫자, 단어 문자(알파벳, 숫자, 밑줄), 공백 문자와 각각 일치한다.
let regex = /\d\w\s/g;
let str = "1a 2b 3c 4d";
let match;
while ((match = regex.exec(str)) !== null) {
console.log(`Found ${match[0]} at position ${match.index}`);
}
위의 코드에서 정규표현식 /\d\w\s/g
는 숫자(\d
), 단어 문자(\w
), 그리고 공백 문자(\s
) 순서로 나타나는 패턴을 찾는다. 따라서 “4d”를 제외한 "1a ", "2b ", "3c "가 매칭된다.
Found 1a at position 0
Found 2b at position 4
Found 3c at position 8
\D
, \W
, \S
: 숫자가 아닌 것, 단어 문자가 아닌 것(특수문자 등), 공백이 아닌 것과 각각 일치한다.
let regex = /\D\W\S/g;
let str = "a#1 b@2 c&3";
let match;
while ((match = regex.exec(str)) !== null) {
console.log(`Found ${match[0]} at position ${match.index}`);
}
위의 코드에서 정규표현식 /\D\W\S/g
는 숫자가 아닌 문자(\D
), 단어 문자가 아닌 문자(\W
), 그리고 공백이 아닌 문자(\S
) 순서로 나타나는 패턴을 찾습니다. 따라서 "a#1", "b@2", "c&3" 모두 매칭된다.
Found a#1 at position 0
Found b@2 at position 4
Found c&3 at position 8
( )
: 그룹을 만든다. 그룹 안에 있는 모든 것은 하나의 단위로 취급한다.
let regex = /ca+r/g;
let str = "cr ccar car caar caaar";
let match;
while ((match = regex.exec(str)) !== null) {
console.log(`Found ${match[0]} at position ${match.index}`);
}
위의 코드에서 정규표현식 /(ca)+r/g
는 'ca'가 1번 이상 반복되고 'r'로 끝나는 문자열을 찾는다. 따라서 "car", "caar", "caaar" 등이 매칭된다.
Found car at position 3
Found caar at position 7
Found caaar at position 12
정규 표현식에서 백슬래시 \
는 특수 문자를 이스케이프 하는데 사용된다. 즉, 정규 표현식에서 특별한 의미를 가지는 문자를 일반 문자로 처리하게 한다.
let regex = /ca\+r/g;
let str = "cr car ca+r";
let match;
while ((match = regex.exec(str)) !== null) {
console.log(`Found ${match[0]} at position ${match.index}`);
}
위의 코드에서 정규표현식 /ca\+r/g
는 'c', 'a', '+', 'r' 순서로 나타나는 문자열을 찾는다. 따라서 "ca+r"가 매칭된다. 하지만 "cr", "car"은 중간에 '+'가 없으므로 매칭되지 않는다.
Found ca+r at position 7
정규 표현식에서 파이프 '|'는 OR 연산자로 작동하며, 두 패턴 중 하나와 일치하는 문자열을 찾는다.
let regex = /cat|dog/g;
let str = "I have a cat and a dog.";
let match;
while ((match = regex.exec(str)) !== null) {
console.log(`Found ${match[0]} at position ${match.index}`);
}
위의 코드에서 정규표현식 /cat|dog/g
는 'cat' 또는 'dog'와 일치하는 문자열을 찾는다. 따라서 "cat"과 "dog" 모두 매칭된다.
Found cat at position 9
Found dog at position 18
{ }
: 특정 패턴이 반복되는 횟수를 지정하는데 사용된다.
{n}
: 바로 앞의 요소가 정확히 n번 반복되어야 함을 의미한다.{n,}
: 바로 앞의 요소가 최소한 n번 반복되어야 함을 의미한다.{n,m}
: 바로 앞의 요소가 최소 n번 이상, 최대 m번 이하 반복되어야 함을 의미한다.