정규식
정규표현식 사용방법
var searchPattern = /+s/ig;
RegExp 객체
메소드 | 인자 | 사용설명 |
---|---|---|
test | 문자열 | 입력된 문자열이 정규 효편식에 부합하는지를 판단 |
exec | 문자열 | 정규표현식과 매칭되는 것을 찾아 반환, 매칭을 찾을수 없을 경우 null 반환 |
플래그
- i : 대소문자를 구분하지 않는다
- g : 전역매칭
- m: 여러줄 매칭
※ String 객체의 regex 메소드인 등을 주로 사용
정규표현식 | 사용설명 |
---|---|
\ | \ 뒤의 일반문자는 특수문자로 인식, \ 뒤의 특수문자는 기호로 인식 |
\s | 공백문자 |
\d | 숫자 |
\D | 숫잔가 아닌 문자 |
\w | 아파벳 대소문자+숫자 [A-Za-z0-9] |
\W | 아파뱃 대소문자+숫자가 아닌 문자 |
\+, \-, \* | 기호 +, 기호 -, 기호 * |
* | 0회 이상 반복 |
+ | 1회 이상 반복 |
? | 0개 또는 1개의 문자 매칭 |
. | 1개의 문자 매칭 |
^ | 시작기호, 또는 "~제외한" |
$ | 끝기호 |
[] | []안에 문자범위를 매칭 |
() | 매칭된 다음 그 부분을 저장한다 매칭된 내용은 $1,$2,~$9로 저장된다. |
{} | 앞문자의 반복 횟수 지정 |
| | ~또는~ |
pattern0 = "[^가-힣]" '한글만
pattern1 = "[^-0-9]" '숫자만
pattern2 = "[^-a-zA-Z]" '영어만
pattern3 = "[^가-힣a-zA-Z0-9/]" '숫자와 영어 한글만
pattern4 = "<[^>]*>" '태그만
pattern5 = "[^-a-zA-Z0-9/]" '영어 숫자만
이메일 체크 정규식
/^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*.[a-zA-Z]{2,3}$/i;
핸드폰번호 정규식
/^d{3}-d{3,4}-d{4}$/;
일반 전화번호 정규식
/^d{2,3}-d{3,4}-d{4}$/;
아이디나 비밀번호 정규식
/^[a-z0-9_]{4,20}$/;
예제 1) 휴대폰번호
var regExp = /^01([0|1|6|7|8|9]?)-?([0-9]{3,4})-?([0-9]{4})$/;
if ( !regExp.test( document.frm.hp.value ) ) {
alert("잘못된 휴대폰 번호입니다. 숫자, - 를 포함한 숫자만 입력하세요.");
return false
}
예제 2) img 태그에서 파일명 추출하는 정규식
/^<(?:img)[^>]*src="['"]?(?:.*/)?((?:.*?)+.(?:jpg|gif|png))['"]?(?:.*?)/>$/i
var reg = /^<(?:img)[^>]*src="['"]?(?:.*/)?((?:.*?)+.(?:jpg|gif|png))['"]?(?:.*?)/>$/i;
var str1 = '<IMG border="0" src="http://test/bbbb.jpg" />';
var str2 = '<IMG border="0" src="./test/test/bbbb.jpg" />';
var str3 = '<IMG border="0" src="bbbb.jpg" />';
alert(str2.match(reg)[1]);
결과 --> bbbb.jpg
자바스크립트 정규표현식 사용
1. 만들기
var re=/패턴/플래그;
var re=new RegExp("패턴","플래그");
차이 - new로 만들때에는 이스케이프문자는 \는 \\로 해주어야 한다.
var re=/w/;
var re=new RegExp("\w");
2. 플래그(flag)
g (Global 찾기) 패턴에 맞는 모든문자 찾기
i (Ignore Case) 대소문자 무시
m (Multiline) 여러줄
s(dot all) \n 하나의 문자로 인식하겠다.
x(extended) 공백을 무시하겠다
3.
^ 문자열의 시작을 의미 ,m 플래그를 사용할경우 경우는 각 문자열의 시작
$ 문자열의 끝을 의미 ,m 플래그를 사용할경우 경우는 각 문자열의 끝
. 모든 한문자
4.
[문자들] - 괄호안의 문자 하나와 매치
예) [abc] 는 a나 b나 c중 하나를 의미
[^문자들] - 괄호안의 문자가 아닌문자와 매치
예) [^abc] 는 1,2.... d,e.... 등과 매치
[문자1-문자2] - 문자1과 문자2와 그 사이의 값과 매치
예) [a-d] a,b,c,d와 매치
5. (abc) abc와 매치
(패턴) : 해당 패턴과 매칭시키고, 그 부분을 특정 변수에 담는다.
그 변수 이름은 JScript는 $0~$9까지의 변수에 저장이 되고(Perl과 같다.),
VBScript에서는 SubMatches 컬렉션에 저장된다.
괄호기호 자체와 매치시키고 싶다면? /(/와 /)/를 사용한다.
(?:패턴) : 해당 패턴과 매칭은 시키지만, 그 부분을 특정 변수에
담지 않는다. 왜 이게 필요할까?
위의 보기에서 /(z|f)ood/는 "zood" 또는 "food"와 매칭된다고 했는데,
단순히 매칭의 목적으로 사용했지만, "zood"의 경우 "z"가 $0 이란
변수에 저장이 되고 말았다. 이러한 것을 막기 위해서 사용하는 것이
(?:패턴)이다.
(?=패턴) : (?:패턴)과 동일하지만, 패턴과 일치한 부분이후부터
다음 매치가 일어나지 않고 패턴 앞부터 다시 매칭이 진행된다.
즉, 룩업(lookup, lookahead)을 할 뿐이다. /Windows (?=95|98|NT|2000)/ 은
"Windows 2000"의 "Windows" 부분과 매칭이 되며 다음 매칭은
"2000" 다음 부터가 아닌 "Windows" 다음 부터 진행이 된다.
(?!패턴) : (?=패턴)과 반대다. /Windows (?=95|98|NT|2000)/ 은
"Windows 3.1"의 "Windows" 부분과 매칭이 된다.
6. |
좌우 패턴중 하나를 의미
예) (abc|def) abc나 def를 의미
7. *, +, ?
* 앞의 패턴이 0회 또는 그 이상반복됨 예를 들어, "zo*"를 입력하면 "z" 또는 "zoo"를 찾습니다.
+ 앞의 패턴이 1회 또는 그 이상반복됨 예를 들어, "zo+"를 입력하면 "zoo"를 찾지만 "z"는 여기에 포함되지 않습니다.
? 앞의 패턴이 0또는 1회 반복 예를 들어, "a?ve?"를 입력하면 "never"에 있는 "ve"를 찾습니다.
greedy, non-greedy
? : 앞에서 설명했는데, 왜 또? 라고 생각할 것이다.
?은 문맥에 따라 특별한 의미를 갖는다.
패턴 "o*"는 "foooood"와 매칭된다. 당연하다! 하지만, "f"앞의 "o"와
매칭되는 것이 아니다!! "ooooo"와 매칭된 것이다. 즉, 기본으로
정규표현 매칭은 가장 큰 범위를 선택한다. 이것을 greedy하다고 한다.
하지만, 때론 작은 범위에 매칭시킬 필요가 있을 경우가 있다.
(이의 적절한 보기는 잠시 후에 나온다.) "o*?"가 방금 말한
non-greedy 매칭이다.
수량관련 문자인 "*", "+", "?", "{n}", "{n,}", "{n,m}" 다음에 "?"가
나오면 non-greedy 매칭이된다.
잠시, 위에서 "o*?"가 "o"와 매칭된다고 했는데 이상하게 생각한 분이
있었을 것이다. 맞다. "o*?"는 ""와 매칭되었다. "*"는 0개이상임을
잊어선 안된다. "o+?"가 "o"와 매칭된다.
8. {n}, {n,}, {n,m} 패턴의 반복회수
예)
(abc){1,3} abc가 1에서 3회 반복
(abc){1} abc가 1회반복
(abc){,10} abc가 10회 이하 반복
9. 특수문자 (Escapes Character)
\ 일반문자에 \을 붙여서 특수한 용도로 사용한다.
\f 폼피드(?). 용지 공급 문자를 찾습니다.
\r 캐리지리턴
\n 새줄. 줄 바꿈 문자를 찾습니다.
\t 일반 탭문자
\v 세로 탭문자(?)
\0 NUL널문자
[\b] 백스페이스
\s 공백문자
\f, \n, \r, \t, \v, \u00A0, \u2028, \u2029
\S 공백이아닌문자
\w 알파벳문자,숫자,_ [a-zA-Z0-9_]
\W 알파벳문자,숫자,_가 아닌문자 [^a-zA-Z0-9_]).
\d 정수(short for [0-9]).
\D 정수가 아닌 문자 (short for [^0-9]).
\b 단어의 경계 공백,새줄. 예를 들어, "er\b"는 "never"의 "er"를 찾지만 "verb"의 "er"는 찾지 않습니다.
\B 경계가 아닌문자. "ea*r\B"는 "never early"의 "ear"을 찾습니다.
\cX 컨트롤+문자 E.g: \cm matches control-M.
\xhh 핵사코드
\uhhhh 유니코드
복잡한 사용방법이 있고 여러 특수문자와의 조합으로 배우기가 쉽지 않아 간단한 예제를 통해 설명한다.
1. 각 문자와 숫자는 해당 문자 또는 문자열이 테스트할 문자열에 있을경우 true 가된다.
<script>
// 'a' 가 있는 문자열 모두가 TRUE (대소문자 구분)
var filter = /a/
if (filter.test("some test words") == true) { alert("ok"); } else { alert("fail"); }
</script>
<script>
// "about" 가 있는 문자열 모두가 TRUE (대소문자 구분)
var filter = /about/
if (filter.test("some test words") == true) { alert("ok"); } else { alert("fail"); }
</script>
2. 대소문자 구분없이 해당 문자 또는 문자열을 검색할 경우 끝에 i 를 붙인다.
<script>
// 'a' 또는 'A' 가 있는 문자열 모두가 TRUE (대소문자 구분 안함)
var filter = /a/i
if (filter.test("some test words") == true) { alert("ok"); } else { alert("fail"); }
</script>
3. 여러개의 이어지는 내용들을 검색할 경우는 '-' 를 넣어 표현한다.
<script>
// 'a' 에서 'z' 까지중 하나만 있으면 모두가 TRUE (대소문자 구분)
var filter = /[a-z]/
if (filter.test("some test words") == true) { alert("ok"); } else { alert("fail"); }
</script>
4. 여러가지의 문자 또는 문자열을 검색할 경우 '|' 를 넣는다.
<script>
// 'a' 또는 'b' 또는 'c' 가 있는 문자열 모두가 TRUE (대소문자 구분)
var filter = /a|b|c/
if (filter.test("some test words") == true) { alert("ok"); } else { alert("fail"); }
</script>
<script>
// 'a' 에서 'z' 까지 또는 '0' 에서 '9' 까지중 하나만 있으면 모두가 TRUE (대소문자 구분)
var filter = /[a-z]|[0-9]/
if (filter.test("some test words") == true) { alert("ok"); } else { alert("fail"); }
</script>
5. 해당 문자또는 문자열이 없는 경우를 검색할 경우 브래킷('[', ']') 안에 '^' 를 넣는다.
<script>
// 'a' 에서 'z' 까지의 문자가 아닌 문자가 있을 경우 TRUE (대소문자 구분)
var filter = /[^a-z]/
if (filter.test("some test words") == true) { alert("ok"); } else { alert("fail"); }
</script>
6. 문자열의 첫번째 글자가 일치해야할 경우는 '^' 를 브래킷('[', ']') 밖에 넣는다.
<script>
// 'a' 에서 'z' 까지의 문자로 시작하는 문자열일 겨우 TRUE (대소문자 구분)
var filter = /^[a-z]/
if (filter.test("some test words") == true) { alert("ok"); } else { alert("fail"); }
</script>
7. 문자열의 끝쪽 글자가 해당 문자 또는 문자열과 일치해야할 경우는 '$' 를 넣는다.
<script>
// 'a' 에서 'z' 까지의 문자로 끝나는 문자열일 겨우 TRUE (대소문자 구분)
var filter = /[a-z]$/
if (filter.test("some test words") == true) { alert("ok"); } else { alert("fail"); }
</script>
8. 특수문자('', '^', '$', '*', '+', '?', '.', '(', ')', '|', '{', '}', '[', ']')를 검색할 경우는 '' 를 넣는다.
<script>
// '' 가 있는 문자열일 겨우 TRUE (대소문자 구분)
var filter = /\/
if (filter.test("some test words") == true) { alert("ok"); } else { alert("fail"); }
</script>
보기
- 웹 주소
"http://msdn.microsoft.com:80/scripting/default.htm"
위의 주소를 표현할 수 있는 정규표현은 아래와 같다.
/(w+)://([^/:]+)(:d*)?([^# ]*)/
$1 : http
$2 : msdn.microsoft.com
$3 : 80
$4 : /scripting/default.htm
- 중복된 단어를 하나로
중복된 영어단어를 하나로 합치기 위해선, 우선 단어를 찾아야한다.
그리고 단어는 앞 뒤가 단어의 경계이어야한다. (말이 참 이상하지만..)
따라서, 아래와 같은 1차 정규표현을 얻을 수 있다.
/b([a-z]+)b/
연속해서 동일한 두개의 단어... 앞에서 캡쳐한 표현을 다시 활용하면 된다.
그리고, 단어와 단어 사이엔 화이트스페이스가 있다.
/b([a-z]+)s+1b/
- HTML 태그 제거
HTML문서에서 태그를 제거한 문서를 추출하고자 한다.
태그는 "<"와 ">"로 감싸여 있다.
/<.*>.*</.*>/
그런데, 위의 정규표현을 HTML문서에 적용하여 해당 패턴을 "",
빈문자열로 바꾸면 문서는 빈 문서가 되고 만다.
<html>
<title>...</title>
<body>
<font>.... </font>
...
</body>
greedy한 매칭이 기본값이라고 위에서 언급을 했다. 따라서,
위의 HTML 문서를 보면, <html>....</body>로 생각할 수 있다.
따라서, 문서 전체가 사라지는 것이다. 이것을 막기 위해선 "*"뒤에 "?"를
추가하면 된다.
/<.*?>.*?</.*?>/
아직 끝나지 않았다. :)
좀더 정제를 한다면, 올바른 HTML 문서는 <태그명>과 </태그명>이
서로 일치한다. 이것도 적용한다면,
/<.(*?)>.(*?)</1>/
위의 $1에 해당되는 부분을 좀 더 생각해보면, ">"를 제외한 문자로
볼 수 있다. 따라서 최종적으로 아래와 같이 정리된다.
/<(w+)[^>]*?>(.*?)</1>/
- URL
/(?:^|")(http|ftp|mailto):(?://)?(w+(?:[.:@]w+)*?)(?:/|@)([^"?]*?)(?:?
([^?"]*?))?(?:$|")/
- float 상수
/^(((+|-)?d+(.d*)?)|((+|-)?(d*.)?d+))$/ -1.1 1.1 .9 .8
스팸을 보내는 스패머의 IP 주소를 차단하기 위해 .htaccess 파일에 적어 줄 때 많이 사용하는 정규식이다.
/([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3})/
IP 주소의 숫자 부분을 그룹화 한 이유는, 이를 이용해서 다른 문자로 치환할 때 사용하기 위해서이다.
방법 1. /[a-z|A-Z|0-9]+@(naver|daum|hanmail|nate|hotmail|yahoo|gmail|hitel|paran|dreamwiz|lycos).(com|net|co.kr)/
방법 2.
Not : /(@.*@)|(\.\.)|(@\.)|(\.@)|(^\.)/
/^[a-zA-Z0-9\-\.\_]+@[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,3})$/
방법 1. /^0\d{1,2}-\d{3,4}-\d{4}$/
방법 2. /[0-9]{2,4}-[0-9]{3,4}-[0-9]{4}/
HTML 문서를 텍스트 에디터로 열어 편집할 때 하이퍼링크만 검색하기 위한 정규식이다.
/(<a href="["]*[^'"]+['"]*[^>]*>)([^>]*)(</a>)/
a 대신 span, div 등을 넣어서 다른 태그를 검색할 수도 있다.
URL을 검색하기 위한 정규식이다.
/(mms|http|HTTP|ftp|FTP|telnet|TELNET)://(.[^<"')]+)/
/^\d+$/
this.replace(/^\s+/, '').replace(/\s+$/, '');
this.replace(/<\/?[^>]+>/gi, '');
/^\w+$/
/^\W+$/
전자우편 주소:
/^[a-z0-9_+.-]+@([a-z0-9-]+.)+[a-z0-9]{2,4}$/
URL:
/^(file|gopher|news|nntp|telnet|https?|ftps?|sftp)://([a-z0-9-]+.)+[a-z0-9]{2,4}.*$/
HTML 태그 - HTML tags:
/<(/?[^>]+)>/
전화 번호 - 예, 123-123-2344 혹은 123-1234-1234:
/(d{3}).*(d{3}).*(d{4})/
날짜 - 예, 3/28/2007 혹은 3/28/07:
/^d{1,2}/d{1,2}/d{2,4}$/
jpg, gif 또는 png 확장자를 가진 그림 파일명:
/([^s]+(?=.(jpg|gif|png)).2)/
1부터 50 사이의 번호 - 1과 50 포함:
/^[1-9]{1}$|^[1-4]{1}[0-9]{1}$|^50$/
16 진수로 된 색깔 번호:
/#?([A-Fa-f0-9]){3}(([A-Fa-f0-9]){3})?/
적어도 소문자 하나, 대문자 하나, 숫자 하나가 포함되어 있는 문자열(8글자 이상 15글자 이하) - 올바른 암호 형식을 확인할 때 사용될 수 있음:
/(?=.*d)(?=.*[a-z])(?=.*[A-Z]).{8,15}/
정수 숫자 세자리마다 쉼표 찍는 한 줄짜리 정규표현식.
var s = '1234567890';
s.replace(/(d)(?=(d{3})+$)/g, '$1,');
소수점이 포함되어 있다면 $ 대신 \. 로 바꾸면 끝.
문자열 모든 공백 제거
.replace(/(s*)/g, "")
get파라미터 값을 얻어오는 소스
정규식 설명 : 앞에 ?& 두개중 하나가 있고 + 파라미터명= + 값(&# 제외)
function get_param_value( name )
{
name = name.replace(/[[]/,"\[").replace(/[]]/,"\]");
var regexS = "[\?&]"+name+"=([^&#]*)";
var regex = new RegExp( regexS );
var results = regex.exec( window.location.href );
if( results == null )
return "";
else
return results[1];
}
/*-------------------------------------------------------------------------------*/
/*
한글의 경우 키 입력시 바로바로 작업이 안되기 때문에
onchange 와 onblur 등 이벤트도 같이 등록.
*/
// 한글만 입력받기 (초성체 무시)
// 나머지 글자 무시
function nr_han(this_s,type){
/*
type
-> 'c' : 초성 포함
-> 's' : 초성 포함 + 공백 포함
-> '' : 초성, 공백 무시
*/
temp_value = this_s.value.toString();
regexp = '';
repexp = '';
switch(type){
case 'c': regexp = /[^ㄱ-ㅎ가-힣]/g;break;
case 's': regexp = /[^ㄱ-ㅎ가-힣s]/g;break;
case '': regexp = /[^가-힣]/g; break;
default : regexp = /[^ㄱ-ㅎ가-힣s]/g;
}
if(regexp.test(temp_value))
{
temp_value = temp_value.replace(regexp,repexp);
this_s.value = temp_value;
}
}
/*-------------------------------------------------------------------------------*/
// 한글만 입력받기 (초성체 포함)
// 나머지 글자 무시
function nr_han_cho(this_s){
nr_han(this_s,'c');
}
/*-------------------------------------------------------------------------------*/
// 한글만 입력받기 (초성체 포함, 공백 포함)
// 나머지 글자 무시
function nr_han_cho_space(this_s){
nr_han(this_s,'s');
}
/*-------------------------------------------------------------------------------*/
function nr_numeng(this_s){
temp_value = this_s.value.toString();
regexp = /[^0-0a-zA-Z]/g;
repexp = '';
temp_value = temp_value.replace(regexp,repexp);
this_s.value = temp_value;
}
/*-------------------------------------------------------------------------------*/
// 나머지 글자 무시
function nr_num(this_s,type){
/*
type
-> 'int' : 양의 정수
-> 'float' : 양의 실수
-> '-int' : 음의 정수 포함
-> '-int' : 음의 실수 포함
*/
temp_value = this_s.value.toString();
regexp = /[^-.0-9]/g;
repexp = '';
temp_value = temp_value.replace(regexp,repexp);
regexp = '';
repexp = '';
switch(type){
case 'int': regexp = /[^0-9]/g; break;
case 'float':regexp = /^(-?)([0-9]*)(.?)([^0-9]*)([0-9]*)([^0-9]*)/; break;
case '-int': regexp = /^(-?)([0-9]*)([^0-9]*)([0-9]*)([^0-9]*)/;break;
case '-float':regexp = /^(-?)([0-9]*)(.?)([^0-9]*)([0-9]*)([^0-9]*)/; break;
default : regexp = /[^0-9]/g; break;
}
switch(type){
case 'int':repexp = '';break;
case 'float':repexp = '$2$3$5';break;
case '-int': repexp = '$1$2$4';break;
case '-float':repexp = '$1$2$3$5'; break;
default : regexp = /[^0-9]/g; break;
}
temp_value = temp_value.replace(regexp,repexp);
this_s.value = temp_value;
}
// 양의 정수만 입력받기
function nr_num_int(this_s){
nr_num(this_s,'int');
}
// 양의 실수만 입력받기
function nr_num_float(this_s){
nr_num(this_s,'float');
}
/*-------------------------------------------------------------------------------*/
// 영어만 입력받기 (대소문자)
// 나머지 글자 무시
function nr_eng(this_s,type){
temp_value = this_s.value.toString();
regexp = '';
repexp = '';
switch(type){
case 'small':regexp = /[^a-z]/g;break;
case 'big':regexp = /[^A-Z]/g;break;
case 'all':regexp = /[^a-z]/i;break;
default :regexp = /[^a-z]/i;break;
}
temp_value = temp_value.replace(regexp,repexp);
this_s.value = temp_value;
}
// 영어만 입력받기 (소문자)
// 나머지 글자 무시
function nr_eng_small(this_s){
nr_eng(this_s,'small');
}
// 영어만 입력받기 (대문자)
// 나머지 글자 무시
function nr_eng_big(this_s){
nr_eng(this_s,'big');
}
// 전화번호 규격에 맞게 DDD-MM~M-XXXX
// 나머지 글자 무시
function nr_phone(this_s)
{
temp_value = this_s.value.toString();
temp_value = temp_value.replace(/[^0-9]/g,'');
temp_value = temp_value.replace(/(0(?:2|[0-9]{2}))([0-9]+)([0-9]{4}$)/,"$1-$2-$3");
this_s.value = temp_value;
}
/*-------------------------------------------------------------------------------*/
// 주민등록 번호 규격에 맞게 123456-1234567 //검증하지 않음.
// 나머지 글자 무시
function nr_jumin(this_s)
{
temp_value = this_s.value.toString();
temp_value = temp_value.replace(/[^0-9]/g,'');
temp_value = temp_value.substr(0,13);
temp_value = temp_value.replace(/([0-9]{6})([0-9]{7}$)/,"$1-$2");
this_s.value = temp_value;
}
/*-------------------------------------------------------------------------------*/
// 사업자 등록 번호 규격에 맞게 123-12-12345 //검증하지 않음.
// 나머지 글자 무시
function nr_company_num(this_s)
{
temp_value = this_s.value.toString();
temp_value = temp_value.replace(/[^0-9]/g,'');
temp_value = temp_value.substr(0,10);
temp_value = temp_value.replace(/([0-9]{3})([0-9]{2})([0-9]{5}$)/,"$1-$2-$3");
this_s.value = temp_value;
}
//----------------------------------------------=--------------------------------------