[자바스크립트] 정규표현식
[자바스크립트] 정규표현식
프로그래머스 코딩테스트 신규 추천 아이디 문제를 풀었다, 나는 복잡하고 긴 코드를 짜서 풀었지만 정규 표현식만 사용하여 풀수 있다는 것에 충격을 받았다. 정규표현식이 특정한 패턴의 문자를 걸러내고 조합하는 코드를 짜는데 있어서 얼마나 유용하고 코드가 간결화해질 수 있는지 느껴서 포스팅 하게 되었다.
신규 추천 아이디 문제
1
2
3
4
5
6
7
8
1단계 new_id의 모든 대문자를 대응되는 소문자로 치환합니다.
2단계 new_id에서 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거합니다.
3단계 new_id에서 마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환합니다.
4단계 new_id에서 마침표(.)가 처음이나 끝에 위치한다면 제거합니다.
5단계 new_id가 빈 문자열이라면, new_id에 "a"를 대입합니다.
6단계 new_id의 길이가 16자 이상이면, new_id의 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거합니다.
만약 제거 후 마침표(.)가 new_id의 끝에 위치한다면 끝에 위치한 마침표(.) 문자를 제거합니다.
7단계 new_id의 길이가 2자 이하라면, new_id의 마지막 문자를 new_id의 길이가 3이 될 때까지 반복해서 끝에 붙입니다.
파라미터로 랜덤한 인풋값을 넣었을 때 위 조건에 맞아 떨어지는 문자열이 리턴되어야한다.
1단계
모든 대문자를 소문자로 치환하는 함수 toLowerCase()
함수를 적용하여 대문자로 변경한다.
2단계
알파벳, 소문자, 숫자, 하이픈(-), 언더바(_), 점(.) 을 제외한 나머지를 공백을 변환해 준다.
[^문자] 괄호 안에 문자를 제외 한다는 의미이다.
\w 는 영어 알파벳, 숫자, 언더바(_)를 의미한다.
replace()
함수를 이용해서 첫번째 인자로 모든 문자를 의미하는 g를 마지막에 포함한 /[^\w-.]/g
두번째 인자로 바꿔줄 문장을 넣으면 되는데 저문자를 제외하고 나머지는 지울거기 때문에 ‘’ 공백을 넣어준다.
replace(/[^\w-.]/g,'')
3단계
이부분에서 필자는 반분문을 써서 해결했지만.. 정규 표현식을 사용하게 된다면 아주 간단하게 해결할 수 있다. 정규 표현식에서 일반 문자는 그냥 사용하면되지만 특수문자를 검색하게 될 경우 앞에 역슬래시() 를 붙여야한다. 정규 표현식에서 +
는 검색하는대상이 연속해서 중복되는 경우를 검색하게 된다. 예를 들어 /c+/ 하게되면 c가 한개 있는 경우와 ccc 이런식으로 여러개 나열된 경우를 하나로 검색하게 된다. 하지만 낱개의 글자가 아니라 단어나 문장일 경우는 () 괄호를 통해 검색해야 중복된 검색을 선택 할 수 있다. 말이 어려우니 예제로 넘어가자
1
2
let ko = 'kkkkkkkokokokokkkkoko'
ko = ko.replace(/k+/g, 'k') // kokokokokoko
중복된 k가 한개로 사라졌다 +
떄문에 k와 kkkk를 동일하게 검색대상이 된것이다.
- 낱개의 글자가 아니라 ko라는 단어를 적용해 보자
1
2
let ko = 'kkkkkkkokokokokkkkoko'
ko = ko.replace(/ko+/g, 'ko') //kkkkkkkokokokokkkkoko
예상과는 다르게 ko가 중복되서 출력된다. 그이유는 ko라는 단어에 + 가 아닌 o라는 단어에 +가 되어 충복된 o을 ko로 변환 시킨 것이다
이러한 문제를 해결하기 위해 그룹화() 시켜서 검색하게 된다.
1
2
let ko = 'kkkkkkkokokokokkkkoko'
ko = ko.replace(/(ko)+/g, 'ko') //kkkkkkkokkkko
결론적으로 중복되는 .
을 하나로 변경하기 위해서는 점(.)은 특수 문자기 때문에 역슬래시()가 앞에 붙어야 일반문자로 인식한다.
replace(/\.+/g, '.')
4단계
시작을 의미하는 ^문자열
과 마지막을 의미하는 문자열$
을 정규표현식에서 OR을 의미하는 |
을 사용해서 첫번째 또는 마지막 쩜을 공백으로 변환시킨다.
replace(/^\.|\.$/g, '')
5단계
시작과 마지막이 공백일 경우를 의미하는 검색패턴 ^$
replace(/^$/g, 'a')
6단계
6단계 첫 번째 조건인 15개의 문자를 제외한 나머지를 지우기
.slice(0, 15)
두 번째 조건문자의 마지막이 점(.)일경우 제거
.replace(/\.$/g, '')
7단계
7단계는 반복문을 사용해서 푸는게 젤 이상적인 방법인거 같다. 하지만 주제가 정규표현식으로 해결하기이니 만큼 정규표현식을 사용해보자, $숫자
는 그룹조건을 의미한다. 예를 들어 $1 이라고 했을 때 첫번 째 그룹화된 조건을 의미하게 되고 $2라고 했을 때는 다음으로 그룹화된 검색 조건을 의미한다.
1
2
var str = "JohnSmith";
var newstr = str.replace(/(Jo)(hn)/g, "$2$1"); //hnJoSmith
첫 번째 그룹화된 문자는 Jo 이고 두번째 그룹화된 문자는 hn이다. 그래서 코드를 해석해보자면 John을 hnJo로 바꿔라가 되는 것 이다.
이러한 특징을 이용해 7단계 문제를 정규식으로 풀어보자
역슬래시 점이 아닌 특수문자로써 .
은 모든 문자열을 의미한다. 시작과끝에 문자열이 하나밖에없다면 그문자열을 3개로 만든다.
replace(/^(.)$/g, '$1$1$1')
시작과 끝에 문자열이 2개밖에 없다면 2번째 문자로 3개의 문자열로 만든다.
replace(/^(.)(.)$/g, '$1$2$2')
정규표현식
정규표현식은 “특정 패턴의 문자”를 찾기 위한 표현 방식입니다. 정규 표현식을 사용하여 단순한 패턴을 검색하고자 할 때는 찾고자 하는 문자열을 직접 나열하면 됩니다. 하지만 숫자만을 검색하거나, 띄어쓰기를 찾는 등 정확히 일치하는 패턴보다 더 복잡한 조건을 사용하려면 특수 문자를 사용해야 합니다.
정규표현식 사용법
1. 정규 표현식 형식
/패턴/플래그
- 슬래시(/) 사이에는 매칭시킬 패턴을 써준다.
- 슬래시(/) 다음에는 옵션을 설정하는 플래그를 써준다.
패턴은 찾고자하는 특정 패턴의 문자를 말하는 것이고 플래그는 하나만 찾을지, 모두 다 찾을지 등을 설정하는 옵션이라고 보면된다.
2. 정규표현식 매칭 패턴종류
패턴 | 의미 |
---|---|
a-zA-Z | 영어알파벳(-으로 범위 지정) |
ㄱ-ㅎ가-힣 | 한글 문자(-으로 범위지정) |
0-9 | 숫자(-으로 범위 지정) |
. | 모든 문자열(숫자, 한글, 영어, 특수기호, 공백 모두 단, 줄바꿈X) |
\d | 숫자 |
\D | 숫자가 아닌것 |
\w | 영어 알파벳, 숫자, 언더스코어(_) |
\W | 영어 알파벳, 숫자, 언더스코어(_)가 아닌것 |
\s | space 공백 |
\S | space 공백이 아닌것 |
\특수기호 | 특수기호 |
\ | 역슬래시() 다음에 일반 문자가 나오면 이스케이프문자로 해석하고, 특수 문자가 나오면 일반 문자로 해석한다. |
3. 정규표현식 검색 패턴
기호 | 의미 | |
---|---|---|
OR | ||
[] | 괄호안의 문자들 중 하나 | |
[^문자] | 괄호안의 문자를 제외한 것 | |
^문자열 | 특정 문자열로 시작(괄호 없음 주의) | |
문자열$ | 특정 문자열로 끝남 | |
() | 그룹 검색 및 분류(match메서드에서 그룹별로 묶어줌) | |
(?: 패턴) | 그룹 검색(분류X) | |
\b | 단어의 처음/끝 | |
\B | 단어의 처음/끝이 아님 |
4. 정규표현식 갯수(수량) 패턴
- 특정 패턴이 몇번 반복되는지 필터링하는 역할을 한다.
기호 | 의미 |
---|---|
? | 최대 한번(없음 or 한개) |
* | 없거나 있거나(없음 or 있음): 여러개 포함 |
+ | 최소 한개(한개 or 여러개) |
*? | 없거나,있거나 && 없거나, 최대한개=없음 |
{0}과 동일 | |
+? | 최소한개,있거나 && 없거나,최대한개 = 한개 |
{1}과 동일 | |
{n} | n개 |
{Min,} | 최소 Min개 이상 |
{Min, Max} | 최소 Min개 이상, 최대 Max개 이하 |
5. 정규표현식 플래그
- 플래그는 동시에 여러개를 조합하여 사용할 수 있다. 예) gi, gm 등
플래그 | 의미 |
---|---|
g | Global: 모든 문자 검색(안 쓰면 매칭되는 첫 문자만 검색) |
i | Ignore Case: 대소문자 구분 안함 |
m | Mult line: 여러 행의 문자열에 대해 검색 |
s | .(모든 문자 정규식)이 개행 문자 \n도 포함하도록 한다. |
u | unicode 유니코드 전체를 지원 |
y | sticky 문자 내 특정 위치에서 검색을 진행하는 ‘sticky’ 모드 활성화 |