알고리즘을 풀면서 가장 필요했던 부분들과 부족한 부분들 정리를 해볼까 한다.
(1) 정규 표현식
정규표현식은 "특정 패턴의 문자열"을 찾기 위한 표현 방식이다.
(이런걸 형식 언어, formal languange라고 합니다.)
따라서 문자열 비교나 바꾸기 등에 많이 사용되서 알고리즘에 매우 효율적이라고 생각한다.
정규 표현식을 만드는 방법
- 정규 표현식 리터럴
const exam = /abcd/
- RegExp 객체의 생성자 호출
const exam = new RegExp('abcd')
정규 표현식의 사용법 (리터럴) : /패턴/플래그
- 슬래시 사이에 매칭시킬 패턴을 써준다.
- 슬래시 다음에 옵션을 설정하는 플래그를 써준다.
1) 정규표현식 패턴
- 정규 표현식의 패턴은 크게 세 가지 분류로 나뉜다.
1. 매칭 패턴: 문자, 숫자, 기호 등을 표현할 때 쓰임
2. 검색 패턴: AND, OR, StartWith, EndWith 등의 조합을 만들 때 쓰임
3. 수량 패턴: 패턴이 얼마나 반복되는지 필터링할 때 쓰임
- 매칭 패턴 (-로 범위를 지정하거나 \로 특수문자나 숫자 등을 나타낸다)
패턴 | 의미 |
a-zA-z | 알파벳 소문자, 대문자 |
ㄱ-ㅎ가-힣 | 한글 문자 |
0-9, \d | 숫자 |
\D | 숫자 외의 것 |
\w | 영어(word), 숫자, _ |
\W | \w 그 외의 것 |
\s | 스페이스(공백) |
\S | 스페이스가 아닌 것 |
\특수기호 | 특수기호 (\.\, 등) |
. | 모든 문자 |
- 검색 패턴 (주로 매칭 패턴을 감싸거나 패턴 앞, 중간, 뒤쪽 등에 사용)
패턴 | 의미 |
| | OR |
[] | 괄호 안의 문자들 중 하나 |
[^문자] | 괄호 안의 문자 제외한 것 |
^문자열 | 특정 문자열로 시작 |
문자열$ | 특정 문자열로 끝남 |
() | 그룹 검색 및 분류 |
(?: 패턴) | 그룹 검색 |
\b | 단어의 처음/끝 |
\B | 단어의 처음/끝이 아닌 것 |
- 수량 패턴 (주로 매칭 패턴 뒤에 쓰며, 매칭 패턴의 반복을 필터링 함)
패턴 | 의미 |
? | 패턴이 없거나 한번 있음 |
* | 패턴이 없거나 있을 수 있음(여러번 가능) |
+ | 패턴이 최소 한개 있음(여러번 가능) |
{n} | 패턴이 n개 있음 |
{min,} | 패턴이 min개 이상 있음 |
{min,max} | 패턴이 min개 이상 max 개 이하로 있음 |
2) 정규표현식 플래그
- 정규 표현식의 플래그는 패턴 뒤에 나타나며 여러개의 플래그를 사용할 수 있다.
ex) /[^0-9]/gi, /abcd/gm 등
1. g: Global, 모든 문자를 검색함.
2. i: Ignore Case, 대소문자 구분 안함.
3. m: Multi Line, 여러 행의 문자열에 대해 검색함.
3) 정규표현식 메소드
- 정규 표현식을 사용해서 문자열을 찾고 나서 하는 작업들을 메소드라고 한다.
메소드 | 의미 |
문자열.match(/패턴/플래그) | 문자열에서 정규 표현식에 매칭되는 항목들을 배열로 반환한다. |
문자열.replace(/패턴/플래그, 대체 문자열) |
문자열에서 정규 표현식에 해당되는 항목을 대체 문자열로 바꾼다. |
문자열.split(/패턴/플래그) | 문자열을 정규 표현식에 매칭되는 항목으로 쪼개어 배열로 반환한다. |
(/패턴/플래그).test(문자열) | 문자열이 정규 표현식과 매칭되는지 test해서 true, false로 반환한다. |
(/패턴/플래그).exec(문자열) | 문자열과 정규 표현식의 첫번째 매칭 결과를 반환한다. |
4) 정규표현식 사용법
이제 실제로 사용해볼 시간이다.
정규 표현식을 실제로 써볼 수 있었던 알고리즘 문제로 예시를 들어볼까 한다.
밑 문제는 프로그래머스의 신규 아이디 추천 알고리즘 문제를 풀었던 코드 중 일부이다.
function solution(new_id) {
let answer = '';
const pattern1 = /[^a-z0-9-\_\.]/g
new_id = new_id
.toLowerCase("")
.replace(pattern1,'')
.replace(/[.]{2,}/gi, '.')
.replace(/^[.]|[.]$/gi,'');
...
}
new_id로 들어온 문자가 "...!@BaT#*..y.abcdefghijklm" 라고 가정했을 때,
1단계가 모든 대문자를 소문자로 바꾸기,
2단계는 알파벳 소문자, 숫자, 빼기(-), 밑줄(_) 마침표(.)를 제외한 모든 문자를 제거하기,
3단계는 마침표가 두 번 이상 나온 부분은 하나의 마침표로 치환하기,
4단계는 마침표가 처음이나 끝에 위치하면 제거하기
이렇게 4단계까지가 마무리 된 코드이다.
1단계 => "...!@BaT#*..y.abcdefghijklm" => "...!@bat#*..y.abcdefghijklm"
- new_id.toLowerCase() 로 가능
2단계 => "...!@bat#*..y.abcdefghijklm" => "...bat..y.abcdefghijklm"
- const pattern = /[^a-z0-9-\_\.]/g 로 정규 표현식 사용
=> [^(부정)a-z (알파벳 소문자), 0-9(숫자), -(빼기), _(밑줄), .(마침표)] : 2단계 만족하기 위한 정규 표현식
- new_id.replace(pattern, '') 로 pattern에 만족하는 것을 다 아무 문자도 없게 바꿈
3단계 => "...bat..y.abcdefghijklm" => ".bat.y.abcdefghijklm"
- new_id(2단계 마침).replace(/[.]{2,}/gi/, '.')
=> [.] 이라는 문자(패턴)가 2회 이상 나오면 ({2,}) 모든 .을(/gi) '.' 하나로 바꾼다.
4단계 => ".bat.y.abcdefghijklm" => "bat.y.abcdefghijklm"
- new_id(3단계 마침).replace(/^[.]|[.]$/gl, '')
=> 맨 앞에 .이라는 문자(괄호 밖^, ^[.]) 아니면( | )
맨 뒤에 .이라는 문자(괄호 밖 $, [.]$)이 나오면 모든 것(/gi)을 공백으로 바꾼다.
이렇게 4줄로 편하게 위의 많은 조건들을 해결할 수 있었다.
너무 편해서 한 번 정리 해놔야 될 것 같았다. 정리 끝~.~
도움 받았던 블로그
https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Regular_Expressions
https://curryyou.tistory.com/234
감사합니다 ㅎ
'javascript' 카테고리의 다른 글
💪REST API 설계 원칙 (0) | 2022.09.28 |
---|---|
[JavaScript] addEventListener에서의 this 바인딩 (0) | 2022.08.18 |
[JavaScript] JavaScript 로 TDD 및 테스트 코드 작성 하기 (cypress) (0) | 2022.08.15 |