728x90
목차
1. 정규 표현식
- '정규 표현식'은 '문자표현공식', '문자탐색공식'이라고 부르는 연산식과 같은 분류언어입니다.
- 전문가가 사용한는 정규표현식은 초보자에게 외계언어와 같은 느낌의 어려운 공식이지만 문자탐색과 스캔에 있어서 강력한 기능을 갖고있어서, 여러 분야에서 많이 사용되고 있습니다.
- 자바스크립트에서도 많은 '다양한 정규표현식의 적용을 지원'하고 있다.
2. 정규 표현식 사용 방법
2.1. 기본적인 키워드 찾기
string.match(/정규식/); <- 문자열에서 모든 일치를 담은 배열을 반환한다. (일치가 없으면 null 반환)
- g : global ; 모든 패턴에 대해 '전역 탐색'을 한다.
다시 말해, 문자열 전체를 검색하여 지정한 정규표현식 패턴과 일치한 문자열을 찾아 배열에 담는다. - i : ignoreCase ; 대소문자 구분하지 않는다는 설정.
var a = "While some may view this debt forgiveness as a slap in the face to people who were responsible and paid off their student loans";
var b = a.match(/a/); // a 변수 안의 String 내용 중 'a' 글자를 검색 매칭해주세요
console.log(b); // '12'(번째에 있다 -> index=12)
b = a.match(/th/); // a 변수 안의 String 내용 중 'th' 글자를 검색 매칭해주세요
console.log(b); // '20'(번째에 있다 -> index=20)
b = a.match(/is/g); // a 변수 안의 String 내용 중 'th' 글자를 검색 매칭해주세요
console.log(b); // [ 'is' ]
var a = "gabbvdrfabgrdsagfrea";
var c = a.match(/ab*/g); // a변수 안의 String 에서 'a'로 시작하고 'b'가 몇 개든 반복되는 글자를 검색.
console.log(c); // [ 'abb', 'ab', 'a', 'a' ]
2.2. [ ] : 문자 탐색에 사용하는 대괄호
- [ ] : 리스트에서 사용했던 대괄호로 표현
- [ ] 대괄호 안에 검색하고자 하는 글자들을 넣고, 그 포함 유무를 판단한다.
// [abc] : 'a'와 'b'와 'c'가 대상 문자열 안에 하나라도 포함되었는지 판단한다.
let string = 'a';
match = string.match(/[abc]/g);
console.log(match); //[ 'a' ]
string = 'Before';
match = string.match(/[abc]/gi);
console.log(match); //[ 'B' ]
string = 'dude';
match = string.match(/[abc]/g);
console.log(match); //null
- abc 처럼 [ ]가 없는 경우 'abc'단어를 의미하지만
-
[ abc ]는 'a' 또는 'b' 또는 'c'를 의미한다.
a = 'a';
c = a.match(/[abc]/g);
console.log(c); // [ 'a' ]
a = 'before';
c = a.match(/[abc]/g);
console.log(c); // [ 'b' ]
a = 'dude';
c = a.match(/[abc]/g);
console.log(c); // null
a = 'before';
c = a.match(/abc/g);
console.log(c); // null
a = 'grezageagfvrzce';
c = a.match(/z[abc]/g);
console.log(c); // [ 'za', 'zc' ]
// 정규표현식 패턴 끝에 'g'를 쓰면 매칭된 결과를 배열로 하여 모두 찾아내어 담아낸다.
// 'g'가 없으면 맨 첫번째 매칭된 결과를 보여주고, 그 위치값을 index로 보여준다.
2.3. 자주 사용하는 문자열 패턴
[0-9] | 숫자와 매치, 0부터 9까지 아라비아 기호 매칭 = [0123456789] 라고 써야하지만 줄여서 사용하는 것이다. |
[a-z] | 문자 소문자와 매치, 소문자 a 부터 z까지의 글자 매칭 = [abcdefghijklmnopqrstuvwxyz] |
[A-Z] | 문자 대문자와 매치, 대문자 A 부터 Z까지의 글자 매칭 = [ABCDEFGHIJKLMNOPQRSTUVWXYZ] |
[a-zA-Z] | 아라비아 숫자를 제외한 대소문자와 매칭 |
[a-zA-Z0-9] | 아라비아 숫자, 소문자, 대문자 모두 매칭 |
\d | 숫자와 매치 = [0-9]와 동일한 표현이다. |
\D | 숫자가 아닌것과 매치 |
\s | whitespace(공백)와 매치 = [\t\n\r\f\v]와 같은 표현 |
\S | whitespace(공백)가 아닌것과 매치 |
\w | 문자와 숫자들과 매치 [0-9a-zA-Z]와 같은 표현 |
\W | 문자와 숫자가 아닌 것과 매치 |
// 소문자 검색
a = 'ABCDEfGH';
b = a.match(/[a-z]/g);
console.log(b); // [ 'f' ]
// 숫자 검색
a = 'ABCDEfGH0';
// b = a.match(/[0-9]/g);
b = a.match(/[\d]/g);
console.log(b); // [ '0' ]
// 공백 검색
a = 'ABCDE fGH';
b = a.match(/[\s]/g);
console.log(b); // [ ' ' ]
// 글자(문자와 숫자) 검색
a = '$#%^$!%^k&$%(';
b = a.match(/[\w]/g);
console.log(b); // [ 'k' ]
2.4. Dot( . )
- Dot(.) - 줄 바꿈 글자인 '\n'을 제외한 모든 글자와 매칭된다.
- /a.b/ : a와 b 사이에 어떤 글자가 들어와도 매칭된다.
- a + "모든문자" + b
string = 'aab';
match = string.match(/a.b/g);
console.log(match); //[ 'aab' ]
string = 'a0b';
match = string.match(/a.b/g);
console.log(match); //[ 'a0b' ]
string = 'ab';
match = string.match(/a.b/g);
console.log(match); //null
2.4.1. a.b와 a[.]b의 차이점
- [ . ] : 괄호안에 '\n'을 제외한 모든 문자를 표시하는 것이 아닌, 괄호안의 ' . '을 찾는 것.
- 'a.b'는 매칭이 되지만 'aab'는 매칭되지 않는다.
a = 'aab';
b = a.match(/a.b/g);
console.log(b); // [ 'aab' ]
a = 'aab';
b = a.match(/a[.]b/g);
console.log(b); // null
a = 'a0b';
b = a.match(/a.b/g);
console.log(b); // [ 'a0b' ]
a = 'a.b';
b = a.match(/a.b/g);
console.log(b); // [ 'a.b' ]
a = 'ab';
b = a.match(/a.b/g);
console.log(b); // null
2.5. 반복 ( * )와 ( + )
* | 앞에 있는 글자의 반복 횟수를 '0회차부터 카운트'하여 반복된 문자열을 탐색 |
+ | 앞에 있는 글자의 반복 횟수를 '1회차부터 카운트'하여 반복된 문자열을 탐색 |
// 정규표현식이 'ca*t'일 경우
string = 'ct';
match = string.match(/ca*t/g);
console.log(match); //[ 'ct' ]
string = 'cat';
match = string.match(/ca*t/g);
console.log(match); //[ 'cat' ]
string = 'caaaaat';
match = string.match(/ca*t/g);
console.log(match); //[ 'caaaaat' ]
// 정규표현식이 'ca+t' 일 경우
string = 'ct';
match = string.match(/ca+t/g);
console.log(match); // null
string = 'cat';
match = string.match(/ca+t/g);
console.log(match); //[ 'cat' ]
string = 'caaaat';
match = string.match(/ca+t/g);
console.log(match); //[ 'caaaat' ]
a = 'caaaat';
b = a.match(/ca*t/g);
console.log(b); // [ 'caaaat' ]
a = 'caaaat';
b = a.match(/ca+t/g);
console.log(b); // [ 'caaaat' ]
a = 'ct';
b = a.match(/ca*t/g);
console.log(b); // [ 'ct' ]
a = 'ct';
b = a.match(/ca+t/g);
console.log(b); // null
2.6. 반복 {m,n}와 ( ? )
{m} |
앞에 위치한 글자의 m회 반복 매칭
|
{m,n} |
앞에 위치한 글자의 m회부터 n회 반복 매칭
|
? |
앞에 위치한 글자의 0회 또는 1회 반복 매칭
|
// 정규표현식 : 'ca{2}t'
string = 'cat';
match = string.match(/a{2}/g);
console.log(match); // null
string = 'caat';
match = string.match(/a{2}/g);
console.log(match); // [ 'aa' ]
// 정규표현식 : 'ca{2,4}t'
string = 'cat';
match = string.match(/ca{2,4}t/g);
console.log(match); // null
string = 'caat';
match = string.match(/ca{2,4}t/g);
console.log(match); // [ 'caat' ]
string = 'caaaat';
match = string.match(/ca{2,4}t/g);
console.log(match); // [ 'caaaat' ]
string = 'caaaaat';
match = string.match(/ca{2,4}t/g);
console.log(match); // null
// 정규표현식 : 'ca?t'
string = 'ct';
match = string.match(/ca?t/g);
console.log(match); // [ 'ct' ]
string = 'cat';
match = string.match(/ca?t/g);
console.log(match); // [ 'cat' ]
string = 'caat';
match = string.match(/ca?t/g);
console.log(match); // null
a = 'caat';
b = a.match(/ca{2}t/g);
console.log(b); // [ 'caat' ]
a = 'caaat';
b = a.match(/ca{2,4}t/g);
console.log(b); // [ 'caaat' ]
a = 'caaaat';
b = a.match(/ca{2,4}t/g);
console.log(b); // [ 'caaaat' ]
a = 'caaaaaat';
b = a.match(/ca{2,4}t/g);
console.log(b); // null
a = 'ct';
b = a.match(/ca?t/g);
console.log(b); // [ 'ct' ]
2.7. 연습문제
2.7.1. 연습문제1
- 아래 문자열 중 이름을 제외한 전화번호만 추출하여 출력한다.
a = "park chan ho 010-1234-5678 kim min 010-8888-9999 lee 011-123-2222";
a = "park chan ho 010-1234-5678 kim min 010-8888-9999 lee 011-123-2222";
b = a.match( /\d{3,4}-\d{3,4}-\d{3,4}/g);
console.log(b);
2.7.2. 연습문제2
- 아래 문자열 중 이름을 제외한 이메일주소만 추출하여 출력한다.
a = "park chan ho park@naver.com kim min kim@daum.net lee lee@myhome.com";
a = "park chan ho park@naver.com kim min kim@daum.net lee lee@myhome.com";
b = a.match( /\w*@\w*[.]\w*/g);
console.log(b);
2.8. 메타 문자 ( |, ^, $, \b, \B )
2.8.1. |
- | : or의 의미로 사용.
- 'a|b'는 'a 또는 b'의 의미
let a = "Hello World";
let b = a.match( /Hello|Crow/g);
console.log(b); //[ 'Hello' ]
a = "Welcome Crow";
b = a.match( /Hello|Crow/g);
console.log(b); //[ 'Crow' ]
a = "Hello Crow";
b = a.match( /Hello|Crow/g);
console.log(b); //[ 'Hello', 'Crow' ]
2.8.2. ^
- ^ : ^abc 는 abc로 시작하는 의미의 정규식
a = "Life is too short";
b = a.match(/^Life/g);
console.log(b); // [ 'Life' ]
2.8.3. $
- $ : abc$ 는 abc로 끝나는 의미의 정규식
a = "Life is too short";
b = a.match(/short$/g);
console.log(b); // [ 'short' ]
2.8.4. \b
- \b : Word Boundary 의미로 whitespace로 식별되는 메타 문자
- * 원래 문자열 안에 사용하는 \b는 백스페이스의 역할을 하는 이스케이프 문자이지만
- * 정규표현식에서는 공백의 의미로 사용된다.
a = "no class are all class";
b = a.match(/\bclass\b/g);
console.log(b); // [ 'class', 'class' ]
a = "the declassified algorithm";
b = a.match(/\bclass\b/g);
console.log(b); // null
a = "one subclass is";
b = a.match(/\bclass\b/g);
console.log(b); // null
2.8.5. \B
- \B : whitespace로 구분되지 않는(공백이 아닌 것), 그 외 다른 글자로 구분되는 정규식
a = "no class are all class";
b = a.match(/\Bclass\B/g);
console.log(b); // null
a = "the declassified algorithm";
b = a.match(/\Bclass\B/g);
console.log(b); // [ 'class' ]
a = "one subclass is";
b = a.match(/\Bclass\B/g);
console.log(b); // null
3. 전후방탐색
- 정규표현식으로 구분해내고 매칭한 결과 내용 중, '정규표현식에서 사용되었던 글자를 제외한 나머지를 결과로 얻고자 할 때'
- 예를 들어 http://www.naver.com 에서 "글자들이 반복되고 ' : ' 로끝남"이라는 정규식이 있다면 결과는 'http:' 가 될테지만 원하는 결과가 ' : '를 제외한 'http'만을 목적으로 할 때 사용하는 방식이다.
let a = 'http://www.naver.com';
// '.' : \n이 아닌 모든 글자
let b = a.match(/.+:/g);
console.log(b); // [ 'http:' ]
// 위 결과에서 ':'를 없애고 싶을 때는? -> '전방탐색'을 사용한다.
// 정규식 : (?=정규식 또는 글자)
// 조건에 매칭된 후, 해당(?= 뒤로 이어진) 정규식에 있는 글자는 소모하지 않는다(취하지 않는다)
a = 'http://www.naver.com';
// '.' : \n이 아닌 모든 글자
b = a.match(/.+(?=:)/g);
console.log(b); // [ 'http' ]
3.1. 긍정 / 부정 탐색
전방 긍정 탐색 (전방 탐색) |
(?=value) | 문장에서 value(표현식)값과 일치하는 값을 찾고, 그 앞(왼쪽)으로 찾고자 하는 문자를 매칭한다. |
전방 부정 탐색 | (?!value) | 문장에서 value(표현식)값과 일치하지 않는 값을 찾고, 그 앞(왼쪽)으로 찾고자 하는 문자를 매칭한다. |
후방 긍정 탐색 (후방 탐색) |
(?<=value) | 문장에서 value(표현식)값과 일치하는 값을 찾고, 그 뒤(오른쪽)로 찾고자 하는 문자를 매칭한다. |
후방 부정 탐색 | (?<!value) | 문장에서 value(표현식)값과 일치하지 않는 값을 찾고, 그 뒤(오른쪽)로 찾고자 하는 문자를 매칭한다. |
// 전방 긍정 탐색
a ='스크램블 에그 | 단백질: 10g, 지방: 20g\n햄버거 | 단백질: 40g, 탄수화물: 50g, 지방: 30g\n우유 | 단백질: 20g, 탄수화물: 5g, 지방: 20g';
b = a.match(/(?=.*단백질)(?=.*탄수화물)(?=.*지방).*/gm);
console.log(b);
// [
// '햄버거 | 단백질: 40g, 탄수화물: 50g, 지방: 30g',
// '우유 | 단백질: 20g, 탄수화물: 5g, 지방: 20g'
// ]
// 전방 부정 탐색
a ='스크램블 에그 | 단백질: 10g, 지방: 20g\n햄버거 | 단백질: 40g, 탄수화물: 50g, 지방: 30g\n우유 | 단백질: 20g, 탄수화물: 5g, 지방: 20g';
b = a.match(/(?=.*단백질)(?!.*탄수화물)(?=.*지방).*/gm);
console.log(b);
// [ '스크램블 에그 | 단백질: 10g, 지방: 20g' ]
// 후방 긍정 탐색
a ='스크램블 에그 | 단백질: 10g, 지방: 20g\n햄버거 | 단백질: 40g, 탄수화물: 50g, 지방: 30g\n우유 | 단백질: 20g, 탄수화물: 5g, 지방: 20g';
b = a.match(/.+(?<=단백질.*)(?<=지방.*)/gm);
console.log(b);
// [
// '스크램블 에그 | 단백질: 10g, 지방: 20g',
// '햄버거 | 단백질: 40g, 탄수화물: 50g, 지방: 30g',
// '우유 | 단백질: 20g, 탄수화물: 5g, 지방: 20g'
// ]
// 후방 부정 탐색
a ='스크램블 에그 | 단백질: 10g, 지방: 20g\n햄버거 | 단백질: 40g, 탄수화물: 50g, 지방: 30g\n우유 | 단백질: 20g, 탄수화물: 5g, 지방: 20g';
b = a.match(/.+(?<=단백질.*)(?<!탄수화물.*)(?<=지방.*)/gm);
console.log(b);
// [ '스크램블 에그 | 단백질: 10g, 지방: 20g' ]
3.2. 크롤링 ( 웹 데이터 추출 )
- 주로 html에서 html 태그를 취하지 않고 내용만 발췌할 때 자주 사용한다( 크롤링 )
- 줄이 나뉘어진 데이터를 한줄로 잇고 싶다면 '\'(백슬러쉬)를 활용한다.
- 그러나 데이터가 줄이 나뉜채로 하나의 데이터로 저장하고 싶다면 '\n\'를 활용한다. (줄을 나눈 뒤 잇기)
a= '<html>\n\
<head>\n\
<title>안녕하세요 반갑습니다</title>\n\
</head>\n\
<body>\n\
<div>웹사이트에서 내용을 발췌한다.</div>\n\
</body>\n\
</html>\n';
console.log(a);
// 전후방탐색 적용X
b=a.match(/<div>.+<\/div>/g);
console.log(b); // [ '<div>웹사이트에서 내용을 발췌한다.</div>' ]
// 전후방탐색 (?<=value), (?=value)을 활용
b=a.match(/(?<=<div>).+(?=<\/div>)/g);
console.log(b); // [ '웹사이트에서 내용을 발췌한다.' ]
// 타이틀을 발췌하여 출력
b = a.match(/(?<=<title>).+(?=<\/title>)/g);
console.log(b); // [ '안녕하세요 반갑습니다' ]
3.3. 연습문제
3.3.1. 연습문제 1~5
a = '일반텍스트 파일 : abc.txt, 자동실행파일 : autoexe.bat, 데이터분석파일 : bigdata.at, 더미파일 : gfreag, 알수없는 파일 : korea.bar';
// 연습문제1
// a변수에서 '파일이름.확장자명' 으로 구성된 파일명만 골라서 출력하세요
b = a.match(/\b\w*[.]\w+/g); // [ 'abc.txt', 'autoexe.bat', 'bigdata.at', 'korea.bar' ]
console.log(b);
// 연습문제2
// 파일의 확장자가 'b로 시작하는 파일'을 찾아 출력
b = a.match(/\b\w*[.]b\w+/g); // [ 'autoexe.bat', 'korea.bar' ]
console.log(b);
// 연습문제3
// 파일의 확장자가 'b로 시작하지 않는 파일'을 찾아 출력
b = a.match(/\b\w*[.][^b]\w+/g); // [ 'abc.txt', 'bigdata.at' ]
console.log(b);
// 연습문제4
// 파일의 확장자가 'a 또는 b로 시작하는 파일'을 찾아 출력
b = a.match(/\b\w*[.](a|b)\w+/g); // [ 'autoexe.bat', 'bigdata.at', 'korea.bar' ]
console.log(b);
// 연습문제5
// 파일의 확장자가 'a로 시작하거나, b로 시작하지 않는 파일'을 찾아 출력
b = a.match(/\b\w*[.](a|[^b])\w+/g); // [ 'abc.txt', 'bigdata.at' ]
console.log(b);
3.3.2. 연습문제 6~7
a = '박길동 : park@naver.com, 김하나 : kim@daum.net, 김둘 : ee@myhome.co.kr, 웹사이트 : http://abcdefg.co.kr';
// 연습문제6
// 이메일 주소만 탐색하여 출력
b = a.match(/\b\w*[@]\w+([.]\w*){1,2}/g); // [ 'park@naver.com', 'kim@daum.net', 'ee@myhome.co.kr' ]
console.log(b);
// 연습문제7
// 이메일 주소 중 .net과 .com만 골라 출력
b = a.match(/\b\w*[@]\w+[.](com|net)/g); // [ 'park@naver.com', 'kim@daum.net' ]
console.log(b);
3.3.3. 연습문제 8
a = '현재 접속중인 외부 아이피는 121.66.42.195 이며, 내부 아이피는 192.168.0.2 입니다.';
// 연습문제8
// 위 내용에서 아이피주소만 매칭하여 출력
b = a.match(/\d+[.]\d+[.]\d+[.]\d+/g); // [ '121.66.42.195', '192.168.0.2' ]
// b = a.match(/[012][0-9][0-9][.] ... /g); // [ '121.66.42.195', '192.168.0.2' ]
console.log(b);
4. replace( ) 함수
let a = 'blue sock and red shocks';
b = a.replace(/blue|white|red/g, 'color');
console.log(b); // color sock and color shocks
4.1. 연습문제
4.1.1. 연습문제1
a= 'park 010-1234-5678 , kim 010-8888-9999 , lee 010-1111-2222 ';
// 정규표현식과 replace를 이용하여 전화번호 뒷자리를 모두 마스킹(*로 치환)해주세요.
b = a.replace(/[-]\d{4}\s/g, '-****');
console.log(b) // park 010-1234-****, kim 010-8888-****, lee 010-1111-****
4.1.2. 연습문제2
a= '네이버 - http://www.naver.com , 다음 - http://www.daum.net , 네이트 - http://www.nate.com';
// 위 문자열에서 http를 모두 https로 치환하여 출력
b = a.replace(/\bhttp(?=:)/g, 'https');
console.log(b) // 네이버 - https://www.naver.com , 다음 - https://www.daum.net , 네이트 - https://www.nate.com
300x250