https://poiemaweb.com/js-regexp
1. 정규표현식(Regular Expression)
정규표현식(Regular Expression)은 문자열에서 특정 내용을 찾거나 대체 또는 발췌하는데 사용한다.
반복문과 조건문을 사용한 복잡한 코드도 정규표현식으로 간단하게 표현할 수 있다.
하지만 정규표현식은 주석이나 공백을 허용하지 않고 여러가지 기호를 혼합하여 사용하기 때문에 가독성이 좋지 않다.
정규표현식은 리터럴 표기법으로 생성할 수 있다. 정규 표현식 리터럴은 아래와 같이 표현한다.
정규표현식을 사용하는 자바스크립트 메소드
RegExp.prototype.exec : 첫 번째 일치 결과를 배열로 반환합니다. (검색 위치 lastindex 를 기억)
RegExp.prototype.test : 패턴을 검색하여 일치하는지 여부를 불리언 값으로 반환
String.prototype.match : 일치하는 모든 문자열을 배열로 반환
String.prototype.replace : 해당 패턴을 다른 문자열로 대체
String.prototype.search : 첫 번째 일치하는 인덱스를 반환
String.prototype.split : 정규 표현식 또는 구분자로 분할하여 배열로 반환
const targetStr = 'This is a pen.';
const regexr = /is/ig;
// RegExp 객체의 메소드
console.log(regexr.exec(targetStr)); // [ 'is', index: 2, input: 'This is a pen.' ]
console.log(regexr.test(targetStr)); // true
// String 객체의 메소드
console.log(targetStr.match(regexr)); // [ 'is', 'is' ]
console.log(targetStr.replace(regexr, 'IS')); // ThIS IS a pen.
// String.prototype.search는 검색된 문자열의 첫번째 인덱스를 반환한다.
console.log(targetStr.search(regexr)); // 2 ← index
console.log(targetStr.split(regexr)); // [ 'Th', ' ', ' a pen.' ]
1.1 플래그
플래그는 옵션이며 사용하지 않은 경우, 첫번째 매칭한 대상만을 검색하고 종료한다.
const targetStr = 'Is this all there is?';
// 문자열 is를 대소문자를 구별하여 한번만 검색한다.
let regexr = /is/;
console.log(targetStr.match(regexr)); // [ 'is', index: 5, input: 'Is this all there is?' ]
// 문자열 is를 대소문자를 구별하지 않고 대상 문자열 끝까지 검색한다.
regexr = /is/ig;
console.log(targetStr.match(regexr)); // [ 'Is', 'is', 'is' ]
console.log(targetStr.match(regexr).length); // 3
비교
g
const target = 'Is this all there is?';
const regexGlobal = /is/g;
// Global 플래그 사용 예시
console.log("Global flag:");
console.log(regexGlobal.exec(target)); // ["is", index: 5, input: 'Is this all there is?']
console.log(regexGlobal.exec(target)); // ["is", index: 18, input: 'Is this all there is?']
console.log(regexGlobal.exec(target)); // null (다음 일치하는 부분 없음)
i
const target = 'Is this all there is?';
const regexGlobal = /is/gi;
// Global 플래그 사용 예시
console.log("Global flag:");
console.log(regexGlobal.exec(target)); // ["is", index: 0, input: 'Is this all there is?']
console.log(regexGlobal.exec(target)); // ["is", index: 5, input: 'Is this all there is?']
console.log(regexGlobal.exec(target)); // ["is", index: 18, input: 'Is this all there is?']
y (Sticky)
- exec() 메서드가 특정 위치(lastIndex)에서 검색
- 해당 문자열이 패턴과 다르면 바로 null 반환
const target = 'Is this all there is?';
const regexSticky = /is/y;
// 첫 번째 호출: lastIndex는 0이기 때문에 문자열의 처음부터 검색을 시작합니다.
console.log(regexSticky.exec(target)); // null (일치하는 부분 없음)
// 두 번째 호출: lastIndex가 5부터 시작하여 'is'를 찾습니다.
regexSticky.lastIndex = 5; // 'is'가 있는 위치로 lastIndex 설정
console.log(regexSticky.exec(target)); // ["is", index: 5, input: 'Is this all there is?']
// 세 번째 호출: lastIndex가 10부터 시작하여 'is'를 찾습니다.
regexSticky.lastIndex = 10; // 'is'가 없는 위치로 lastIndex 설정
console.log(regexSticky.exec(target)); // null (일치하는 부분 없음)
u (Unicode)
- 유니코드를 처리할 때 사용됩니다. 특히 유니코드 코드 포인트가 16진수로 표시된 문자열을 처리할 때 필요합니다.
- 예를 들어, /^\uD83D/u 패턴은 유니코드 코드 포인트로 이모지를 찾을 수 있습니다.
1.2 패턴
패턴에는 검색하고 싶은 문자열을 지정한다.
이때 문자열의 따옴표는 생략한다.
따옴표를 포함하면 따옴표까지도 검색한다.
또한 패턴은 특별한 의미를 가지는 메타문자(Metacharacter) 또는 기호로 표현할 수 있다.
https://hamait.tistory.com/342
사용 예시
const targetStr = 'AA AAA BB ZZ Aa Bb';
// 임의의 문자 3개
const regexr1 = /.../;
console.log(targetStr.match(regexr1)); // [ 'AA ', index: 0, input: 'AA AAA BB ZZ Aa Bb', groups: undefined ]
// 임의의 문자 3개를 반복하여 검색
const regexr2 = /.../g;
console.log(targetStr.match(regexr2)); // [ 'AA ', 'AAA', ' BB', ' ZZ', ' Aa', ' Bb' ]
// 'A'가 한번이상 반복되는 문자열('A', 'AA', 'AAA', ...)을 반복 검색
const regexr6 = /A+/g;
console.log(targetStr.match(regexr6)); // [ 'AA', 'AAA', 'A' ]
// 'A' 또는 'B'를 반복 검색
const regexr7 = /A|B/g;
console.log(targetStr.match(regexr7)); // [ 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'A', 'B' ]
// 'A' 또는 'B'가 한번 이상 반복되는 문자열을 반복 검색
// 'A', 'AA', 'AAA', ... 또는 'B', 'BB', 'BBB', ...
const regexr8 = /A+|B+/g;
console.log(targetStr.match(regexr8)); // [ 'AA', 'AAA', 'BB', 'A', 'B' ]
const regexr9 = /[AB]+/g;
console.log(targetStr.match(regexr9)); // [ 'AA', 'AAA', 'BB', 'A', 'B' ]
// 'A' ~ 'Z' 또는 'a' ~ 'z'가 한번 이상 반복되는 문자열을 반복 검색
const regexr11 = /[A-Za-z]+/g;
// 아래와 동일하다.
// const regexr = /[A-Z]+/gi;
console.log(targetStr.match(regexr11)); // [ 'AA', 'AAA', 'BB', 'ZZ', 'Aa', 'Bb' ]
\d 는 숫자를 의미한다.
const targetStr = 'AA BB Aa Bb 24,000';
// '0' ~ '9'가 한번 이상 반복되는 문자열을 반복 검색
let regexr = /[0-9]+/g;
console.log(targetStr.match(regexr)); // [ '24', '000' ]
let regexr2 = /[\d]+/g;
console.log(targetStr.match(regexr2)); // [ '24', '000' ]
\w는 알파벳과 숫자를 의미한다. \W는 \w와 반대로 동작한다.
const targetStr = 'AA BB Aa Bb 24,000';
// 알파벳과 숫자 또는 ','가 한번 이상 반복되는 문자열을 반복 검색
let regexr = /[\w]+/g;
console.log(targetStr.match(regexr)); // [ 'AA', 'BB', 'Aa', 'Bb', '24', '000' ]
1.3 자주 사용하는 정규표현식
특정 단어로 시작하는지 검사한다.
// 'http'로 시작하는지 검사
// ^ : 문자열의 처음을 의미한다.
const regexr = /^http/;
console.log(regexr.test(url)); // true
특정 단어로 끝나는지 검사한다.
const fileName = 'index.html';
// 'html'로 끝나는지 검사
// $ : 문자열의 끝을 의미한다.
const regexr = /html$/;
console.log(regexr.test(fileName)); // true
숫자인지 검사한다.
const targetStr = '12345';
// 모두 숫자인지 검사
const regexr = /^\d+$/;
console.log(regexr.test(targetStr)); // true
하나 이상의 공백으로 시작하는지 검사한다.
const targetStr = ' Hi!';
// 1개 이상의 공백으로 시작하는지 검사
// \s : 여러 가지 공백 문자 (스페이스, 탭 등) => [\t\r\n\v\f]
const regexr = /^[\s]+/;
console.log(regexr.test(targetStr)); // true
아이디로 사용 가능한지 검사한다. (영문자, 숫자만 허용, 4~10자리)
const id = 'abc123';
// 알파벳 대소문자 또는 숫자로 시작하고 끝나며 4 ~10자리인지 검사
// {4,10}: 4 ~ 10자리
const regexr = /^[A-Za-z0-9]{4,10}$/;
console.log(regexr.test(id)); // true
메일 주소 형식에 맞는지 검사한다.
const email = 'ungmo2@gmail.com';
const regexr = /^[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/;
console.log(regexr.test(email)); // true
- ^[0-9a-zA-Z]: 이메일 주소는 숫자 또는 알파벳으로 시작해야 합니다.
- ^는 문자열의 시작을 나타냅니다.
- [0-9a-zA-Z]는 숫자(0-9) 또는 알파벳(a-z, A-Z) 중 하나여야 합니다.
- ([-_\.]?[0-9a-zA-Z])*: 이어지는 문자들은 -, _, . 중 하나가 올 수 있고, 그 뒤에 숫자 또는 알파벳이 올 수 있습니다.
- [-_\.]?는 -, _, . 중 하나가 0 또는 1회 나올 수 있음을 의미합니다.
- [0-9a-zA-Z]는 숫자 또는 알파벳 중 하나입니다.
- *는 바로 앞의 표현이 0회 이상 반복될 수 있음을 나타냅니다.
- @: 이메일 주소의 구분자로 @ 기호가 옵니다.
- [0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*: 도메인 부분입니다. 시작은 숫자 또는 알파벳이며, 이어지는 문자들은 -, _, . 중 하나가 올 수 있고, 그 뒤에 숫자 또는 알파벳이 올 수 있습니다.
- [0-9a-zA-Z]는 숫자 또는 알파벳 중 하나입니다.
- ([-_\.]?[0-9a-zA-Z])*는 앞서 설명한 것과 동일한 반복 패턴입니다.
- \.: 도메인 이름과 TLD(top-level domain)을 구분하는 점(.)이 옵니다.
- [a-zA-Z]{2,3}: 최소 2자에서 최대 3자의 영문자로 된 도메인의 TLD가 옵니다.
- [a-zA-Z]는 영문 알파벳 중 하나입니다.
- {2,3}는 앞의 표현이 2회에서 3회 반복될 수 있음을 나타냅니다.
- $: 정규식의 끝을 나타냅니다.
핸드폰 번호 형식에 맞는지 검사한다.
const cellphone = '010-1234-5678';
const regexr = /^\d{3}-\d{3,4}-\d{4}$/;
console.log(regexr.test(cellphone)); // true
특수 문자 포함 여부를 검사한다.
const targetStr = 'abc#123';
// A-Za-z0-9 이외의 문자가 있는지 검사
let regexr = /[^A-Za-z0-9]/gi;
console.log(regexr.test(targetStr)); // true
// 아래 방식도 동작한다. 이 방식의 장점은 특수 문자를 선택적으로 검사할 수 있다.
regexr = /[\{\}\[\]\/?.,;:|\)*~`!^\-_+<>@\#$%&\\\=\(\'\"]/gi;
console.log(regexr.test(targetStr)); // true
// 특수 문자 제거
console.log(targetStr.replace(regexr, '')); // abc123
2. Javascript Regular Expression
2.1 RegExp Constructor
자바스크립트은 정규표현식을 위해 RegExp 객체를 지원한다.
RegExp 객체를 생성하기 위해서는 리터럴 방식과 RegExp 생성자 함수를 사용할 수 있다.
new RegExp(pattern[, flags])
- pattern 정규표현식의 텍스트
- flags 정규표현식의 플래그 (g, i, m, u, y)
1. 리터럴 방식 예시
// 이메일 주소 검증을 위한 정규표현식 (리터럴 방식)
let emailRegexLiteral = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
// 이메일 주소가 패턴에 맞는지 검사
let email1 = 'example@email.com';
let email2 = 'invalid_email@';
console.log(emailRegexLiteral.test(email1)); // true
console.log(emailRegexLiteral.test(email2)); // false
2. RegExp 생성자 함수 예시
// 동일한 기능을 가진 RegExp 생성자 함수 사용
let patternString = '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$';
let emailRegexConstructor = new RegExp(patternString);
// 이메일 주소가 패턴에 맞는지 검사
let email3 = 'example@email.com';
let email4 = 'invalid_email@';
console.log(emailRegexConstructor.test(email3)); // true
console.log(emailRegexConstructor.test(email4)); // false
일반적으로 리터럴 방식을 선호한다.
정규표현식을 사용하는 메소드
RegExp.prototype.exec : 첫 번째 일치 결과를 배열로 반환합니다. (검색 위치를 기억)
RegExp.prototype.test : 패턴을 검색하여 일치하는지 여부를 불리언 값으로 반환
String.prototype.match : 일치하는 모든 문자열을 배열로 반환
String.prototype.replace : 해당 패턴을 다른 문자열로 대체
String.prototype.search : 첫 번째 일치하는 인덱스를 반환
String.prototype.split : 정규 표현식 또는 구분자로 분할하여 배열로 반환
2.2 RegExp Method
2.2.1 RegExp.prototype.exec(target: string): RegExpExecArray | null ES3
문자열을 검색하여 매칭 결과를 반환한다. 반환값은 배열 또는 null이다.
exec 메소드는 g 플래그를 지정하여도 첫번째 메칭 결과만을 반환한다.
const target = 'Is this all there is?';
const regExp = /is/g;
const res = regExp.exec(target);
console.log(res); // [ 'is', index: 5, input: 'Is this all there is?' ]
const res2 = regExp.exec(target);
console.log(res2); // [ 'is', index: 5, input: 'Is this all there is?' ]
g 플래그를 사용하면 exec() 메서드가 이전 검색 위치에서부터 다음 일치하는 부분을 찾음
2.2.2 RegExp.prototype.test(target: string): boolean ES3
문자열을 검색하여 매칭 결과를 반환한다. 반환값은 true 또는 false이다.
const target = 'Is this all there is?';
const regExp = /is/;
const res = regExp.test(target);
console.log(res); // true
https://chatgpt.com/