티스토리 뷰
정규식
RegExp Object
A regular expression is an object that describes a pattern of characters.
Regular expressions are used to perform pattern-matching and "search-and-replace" functions on text.
정도로 정의할 수 있는데...(구문을 어디서 가져왔는지 모르겠다.;;)
뭐.. 익히 알고 있듯이 문자열에 대한 패턴의 검색, 치환 등을 담당하는 객체이다.
본론으로 들어가서.
정규식(regular expression)의 reg만 들어도 복잡하고 머리아프게 생각하는 사람들이 많다.
나 역시 마찬가지였고, 특히 실무에서는 자바스크립트의 경우 split(), php의 경우 explode() 같은 메서드를 사용하여
문자열 분리 토큰을 입력하고 대충 배열로 떨궈내서 썼었다.
그러나 일일이 배열로 분리 시키는 것보다 바로 치환이나 불리언값 반환이 가능하고, 무엇보다도 특정 문자에 대한 대소문자 구분없이
패턴으로 적용해야 한다면 정규식을 써야 하는 것이 맞다.
정규식의 정의와 스펙
정규식(regular expression)은 패턴화된 캐릭터에 대한 시퀀스를 찾기위한 용도로 쓰인다.
텍스트에서 데이터를 찾거나, 설명에서 특정 부분의 패턴을 찾을 수 있다.
단문자 혹은 완성된 패턴형으로도 검색이 가능하다.
이러한 정규식을 가지고 대표적으로 replace, test, exec, search, match 등 의 메서드와 조합하여 사용한다.
문법
/pattern/modifiers;
예제
var patt = /myAlphabet/i
설명
/myAlphabet/i 는 정규식이다.
myAlphabet 부분이 패턴이다.
i 는 속성으로 대소문자를 구문하지 않는다. (case-insensitive)
속성
i : 대소문자를 구문하지 않는다.
g : 첫 단어만 검색하는경우가 아니면 반드시 써야한다. 전체 문자열에 대해서 전역 패턴 검사를 할 수 있다.
m : 여러 줄에 대한 검색
'[ ]' 를 사용한 범위패턴
'[]'를 사용하면 범위 검색이 가능하다.
[abc] : abc검색
[0-9] : 0 ~ 9까지 검색
[^0-9] : 0 ~ 9를 제외
[ A | B ] : A혹은 B
메타캐릭터
\d : 숫자(digit)를 찾는다.
\/ : 슬래시 ( 실제로 쓰면 /\// 뒷부분이 주석처럼 보이므로 가독성을 위해서 /[\/]/ 를 권장 )
\. : . dot
\s : 모든 공백(whitespace)을 찾는다.
\b : 시작 혹은 끝나는 단어를 찾는다.
\uxxxx : 유니코드 캐릭터로써, 16진수의 수 xxxx 를 찾는다.
replace() : 문자치환
replace()는 특별 문자열을 지정해서 찾거나(searches a string for a specified),
정규식을 추가하거나(or a regular expression) 하여 문자열에 대한 치환이 가능하다.
반환값은 변경된 새로운 문자열이 리턴되며, 실패할 경우 그냥 오리지널 문자열을 반환한다.
This method does not change the original string.
문법
string.replace(searchvalue, newvalue)
설명
var reStr = str.replace('a', 'b'); 라고 쓰면
맨 처음 나타나는 'a' 만 'b'로 바꾸어준다. 단, 최초에 처음 발견되는 a만.
만약 모든 a를 b로 바꾸려면 아래와같이 바꾸어준다.
var reStr = str.replace(/a/gi, 'b');
알파벳 abc를 대소문자 구분없이 def로 바꾸고 싶다면 아래와 같다.
var alphabet = "aBc";
alphabet = alphabet.replace(/abc/gi, 'def'); //결과 def
문자열을 JSON.parse() 하기위해서 홑따옴표 => 쌍따옴표가 되어야한다.
var str = "{'method':'put',token:'1234',company_name:'CJ'}";
str = str.replace(/'/g, '"'); // {"method":"put",token:"1234",company_name:"CJ"}
JSON.parse( str ); // string 에서 json 으로 타입 변환
( 반대는 JSON.stringify 메서드는 JSON을 문자열로 변환한다 )
응용문제
다음의 결과를 예측해 보자.
var str = "Mr Blue has a blue house and a blue car";
var res = str.replace(/blue/g, "red");
var str = "Mr Blue has a blue house and a blue car";
var res = str.replace(/blue/gi, "red");
test() : 문자가 존재하는지 참 거짓 판별
test()메서드는 결과 값을 참, 거짓으로 반환하는 메서드이다.
string.test(value)
만약 알파벳 "e"를 찾는다고 하면
var patt = /e/;
patt.test("Test bset things in life are free!");
의 결과 값은 true 이다.
exec() : 문자가 존재하는지 검사하고 존재하면 찾은 텍스트 자체를 반환한다.
string.exec(value)
/e/.exec("Test bset things in life are free!");
결과 : e
match() : 문자열을 찾고 찾은 문자열들을 배열로 반환한다.
string.match(regexp)
var str = "The rain in SPAIN stays mainly in the plain";
var res = str.match(/ain/gi);
결과 : ain,AIN,ain,ain
※ 정규식의 분량이 많다면 test보다 match를 강력히 권장한다.
search() : 문자열을 찾고 찾은 문자열의 자릿수를 반환한다.
string.search(searchvalue)
문자열을 찾으면 찾은 문자열 위치의 자릿수를 반환하며, 찾지 못하면 -1을 반환한다.
var str = "Mr. Blue has a blue house";
var n = str.search("blue");
결과 : 15
var str = "Mr. Blue has a blue house";
var n = str.search(/blue/i);
결과 : 4
RegExp : 위에서 언급한 정규식과 메서드를 가지고 실무에서 쓸수있는 다양한 상황을 연출해 보았다.
IP 체크하기
function IP_Hidden($ip)
{
if( strlen($ip) == 0 ) $ip = "";
else $ip = preg_replace("|([0-9]{1,3}\.)([0-9]{1,3}\.)([0-9]{1,3}\.)([0-9]{1,3})|","\\1"."\\2"."***."."\\4", $ip);
return $ip;
}
function STR_Hidden($str)
{
if( strlen($str) == 0 ) $str = "";
else $str = str_pad(substr($str, 0, 3), strlen($str), "*");
return $str;
}
소스 :
공백검사 & 공백이 포함되었는지 검사
한글 포함 검사
비밀번호 영문과 숫자조합 6자리 10자리
이메일 형식
이메일 형식 (html5)
. dot 점 제거
/ slash 슬래시 제거
대소문자 치환
<!DOCTYPE html> <html lang="en"> <head> <meta name="Author" content="serpiko@hanmail.net" /> <meta name="description" content="http://serpiko.tistory.com" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> <!--<meta name="viewport" content="width=device-width, initial-scale=1">--> <meta name="format-detection" content="telephone=no" /> <link rel="styleesheet" type="text/css" href="" /> <link rel="shortcut icon" href="" /> <script src="https://code.jquery.com/jquery-1.11.2.min.js"></script> <title>Document</title> <style> * { box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; } div.input_area { margin-bottom :15px; } </style> </head> <body> <div id="wrap"> <div class='input_area'> <label for='inputID_1'>필드가 공백이거나, 공백이 포함되었는지 검사</label> <input type='text' id='inputID_1' name='' value='' /> <button type='button' id='btn_1'>확인</button> </div> <div class='input_area'> <label for='inputID_2'>한글포함 검사</label> <input type='text' id='inputID_2' name='' value='' /> <button type='button' id='btn_2'>확인</button> </div> <div class='input_area'> <label for='inputID_3'>비밀번호 : 영문과 숫자조합, 6~10자리</label> <input type='password' id='inputID_3' name='' value='' /> <button type='button' id='btn_3'>확인</button> </div> <div class='input_area'> <label for='inputID_4'>이메일형식- 정규식</label> <input type='text' id='inputID_4' name='' value='' /> <button type='button' id='btn_4'>확인</button> </div> <div class='input_area'> <form> <label for='inputID_5'>이메일 형식 - HTML5 프로퍼티스사용</label> <input type='email' id='inputID_5' name='' value='' /> <button type='submit' id='btn_5'>확인</button> </form> </div> <div class='input_area'> <label for='inputID_6'>. (dot) 제거하기</label> <input type='text' id='inputID_6' name='' value='' /> <button type='button' id='btn_6'>확인</button> </div> <div class='input_area'> <label for='inputID_7'>/ 제거하기</label> <input type='text' id='inputID_7' name='' value='' /> <button type='button' id='btn_7'>확인</button> </div> <div class='input_area'> <label for='inputID_8'>대소문자 치환하기</label> <input type='text' id='inputID_8' name='' value='' /> <button type='button' id='btn_8_1'>대문자</button> <button type='button' id='btn_8_2'>소문자</button> </div> </div> <script> $(document).ready(function(){ /* -------------------------------------------------------- 공백검사 -----------------------------------------------------------*/ var btn_1 = $('#btn_1'); var regex1 = /\s/g; btn_1.click(function(){ var inputID_1 = $('#inputID_1').val(); if( inputID_1 == '' ) { alert('공백입니다.'); return; } //if( inputID_1.match(regex1) ) if( regex1.test( inputID_1 ) ) { alert('공백이 포함되어있습니다.'); return; } alert('정상입니다.'); }); /* -------------------------------------------------------- 한글포함 검사 -----------------------------------------------------------*/ function korTextCheck($str) { var str = $str; var check = /[ㄱ-ㅎ|ㅏ-ㅣ|가-힣]/; var result = str.match(check); if(result) return true; return false; } var btn_2 = $('#btn_2'); btn_2.click(function(){ var inputID_2 = $('#inputID_2').val(); var bool = korTextCheck(inputID_2); if( bool ) alert('한글입니다.'); else alert('한글이 아닙니다.'); }); /* -------------------------------------------------------- 비밀번호 : 영문+숫자조합, 6~10자리 -----------------------------------------------------------*/ var btn_3 = $('#btn_3'); var eng = /[a-zA-Z]{0,9}/gi; var digit = /[0-9]{0,9}/g; btn_3.click(function(){ var inputID_3 = $('#inputID_3').val(); if( inputID_3 == '' ) { alert('공백입니다.'); return; } if( !inputID_3.match(eng) || !inputID_3.match(digit) || inputID_3.length < 6 || inputID_3.length > 10 ) { alert("공백을 제외한 영문,숫자의 조합 6~10자 사이로 입력해 주십시오."); return; } alert('정상입니다.'); }); /* -------------------------------------------------------- 이메일 : 이메일 형식 검사 -----------------------------------------------------------*/ var btn_4 = $('#btn_4'); var email = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/; btn_4.click(function(){ var inputID_4 = $('#inputID_4').val(); //var bool = email.test( inputID_4 ); var bool = inputID_4.match(email); if( bool ) alert('정상입니다.'); else alert('잘못된 이메일 형식입니다.'); }); /* -------------------------------------------------------- . 제거 -----------------------------------------------------------*/ var btn_6 = $('#btn_6'); var dotReg = /\./g; btn_6.click(function(){ var inputID_6 = $('#inputID_6').val(); var str = inputID_6.replace(dotReg, ''); alert(str); }); /* -------------------------------------------------------- / 제거 -----------------------------------------------------------*/ var btn_7 = $('#btn_7'); //var slashReg = /\//g; var slashReg = /[\/]/g; btn_7.click(function(){ var inputID_7 = $('#inputID_7').val(); var str = inputID_7.replace(slashReg, ''); alert(str); }); /* -------------------------------------------------------- 대소문자 -----------------------------------------------------------*/ var btn_8_1 = $('#btn_8_1'); btn_8_1.click(function(){ var inputID_8 = $('#inputID_8').val(); var str = inputID_8.toUpperCase(); alert(str); }); var btn_8_2 = $('#btn_8_2'); btn_8_2.click(function(){ var inputID_8 = $('#inputID_8').val(); var str = inputID_8.toLowerCase(); alert(str); }); (function(){ console.log('Dev rdy'); })(); }); </script> </body> </html>
심화학습
더욱 상세하고 자세한 내용은 다음을 참조한다.
제공 : 한빛 네트워크
저자 : 로빈 닉슨(Robin Nixon)
역자 : 이대엽
원문 : Using Regular Expressions in PHP and JavaScript
정규 표현식(regular expression)은 다른 여러 언어와 마찬가지로 자바스크립트와 PHP에서도 지원한다. 정규 표현식을 쓰면 가장 강력한 패턴일치(pattern-matching) 알고리즘을 단 한 줄의 표현식으로 작성할 수 있다.
모든 정규 표현식은 반드시 슬래시(/)로 감싸야 한다. 이 슬래시 안에서는 특정 문자가 특별한 의미를 지니며, 이러한 문자를 메타문자(metacharacter)라 한다. 가령 별표(*)는 쉘이나 윈도우 명령 프롬프트에서 쓸 때와 의미가 비슷하다(하지만 의미가 완전히 같지는 않다). 별표는 "부합하려는 텍스트에 바로 앞의 문자가 0개 이상 존재할지도 모른다."라는 뜻이다.
메타문자를 통한 일치
"Le Guin"라는 이름을 찾고 싶고 누군가가 이 이름을 쓸 때 띄어쓰기를 했는지 확신할 수 없다고 가정하자. 텍스트가 이상하게 놓여 있을 수도 있으므로(가령 누군가가 텍스트에 오른쪽 정렬을 위해 별도의 공백을 추가했을 지도 모른다), 다음과 같은 줄을 찾아야 할 수도 있다.
The difficulty of classifying Le Guin's works
그러므로 "LeGuin"뿐 아니라 임의 개수의 공백으로 나뉜 "Le"와 "Guin"도 일치해야 한다. 해결책으로 아래처럼 공백 뒤에 별표를 붙이면 된다.
/Le *Guin/
줄에는 "Le Guin"라는 이름 말고도 여러 가지가 있지만 그래도 괜찮다. 정규 표현식이 해당 줄의 일부분과 일치하면 검사 함수는 참 값을 반환한다. 줄에 "Le Guin"만 포함돼 있는지 확인하려면 어떻게 해야 할까? 나중에 이를 확인하는 방법을 보여주겠다.
항상 공백이 적어도 하나 이상 있다는 사실을 알고 있다고 가정하자. 그런 경우에는 플러스(+) 기호를 쓸 수도 있는데, 이것은 앞에 나오는 문자가 최소한 하나 이상은 존재해야 한다는 뜻이다.
/Le +Guin/
퍼지 문자 일치
점(.)은 특히 유용한데, 이 기호로 줄 바꿈 문자를 제외한 모든 문자와 일치할 수 있다. 텍스트에서 "<"로 시작해서 ">"로 끝나는 HTML 태그를 찾고 있다고 가정하자. 간단하게 다음과 같이 하면 된다.
/<.*>/
점은 어느 문자와도 일치하며 별표(*)는 그러한 일치를 0개 이상의 문자로 확장한다. 따라서 이 패턴은 "< 와 > 사이에 놓인 모든 것(설령 아무것도 없더라도)과 일치한다"라는 뜻이며, <>, <em>, <br /> 등과 일치할 것이다. 하지만 빈 경우인 <>와는 일치하고 싶지 않다면 아래처럼 * 대신 + 기호를 쓰면 된다.
/<.+>/
플러스 기호는 점을 1개 이상의 문자와 일치하는 것으로 확장하여 "<와 >사이에 적어도 하나 이상의 문자가 존재하기만 하면 그 사이에 놓인 모든 것과 일치한다."라는 뜻이 된다. 따라서 이 패턴은 <em>과 </em>, <h1>과 </h1>을 비롯해 아래처럼 태그 사이에 속성이 있는 경우까지 일치할 것이다.
<a href="www.mozilla.org">
하지만 아쉽게도 플러스 기호는 줄의 마지막 >까지 계속해서 일치하므로 다음과 같이,
<h1><b>Introduction</b></h1>
일치된 결과에 1개 이상의 태그가 있을지도 모른다. 나중에 더 나은 해결책을 보여주겠다.
점 문자 자체, 즉 (.)를 일치하고 싶다면 문자 앞에 역슬래시()를 집어넣어 이스케이프 처리를 하면 된다. 이렇게 하지 않으면 점 문자가 메타문자로 작용해 모든 문자와 일치할 것이다. 예를 들어 부동 소수점 수인 "5.0"를 일치하고 싶다고 가정하자. 정규 표현식은 다음과 같다.
/5.0/
역슬래시는 역슬래시 자체를 포함해서(텍스트에서 역슬래시를 일치하는 경우) 모든 메타문자를 이스케이프 처리한다. 하지만 나중에 어떻게 역슬래시가 때때로 그 다음에 오는 문자에 특별한 의미를 부여하는지 살펴보겠다.
방금 부동 소수점 수를 일치해 보았다. 아마 "5."이나 "5.0"도 마찬가지로 모두 부동 소수점 수로서 의미가 같기 때문에 일치하고 싶을 것이다. 또한 "5.00"이나 "5.000" 등도 임의 개수의 0은 허용되므로 일치하고 싶을 것이다. 이러한 일치는 앞서 살펴본 바와 마찬가지로 패턴에 별표를 추가하면 된다.
/5.0*/
괄호를 이용한 그룹화
이번에는 킬로(kilo), 메가(mega), 기가(giga), 테라(tera)와 같은 단위의 증가에 따른 누승을 일치하고 싶다고 가정하자. 즉, 다음과 같은 내용을 일치하고 싶은 것이다.
1,000 1,000,000 1,000,000,000 1,000,000,000,000 ...
여기서도 플러스 기호가 효과가 있지만 ",000"라는 문자열을 그룹화해서 플러스 기호가 해당 문자열을 한 묶음으로 일치하게 해야 한다. 정규 표현식은 다음과 같다.
/1(,000)+ /
괄호는 "플러스 기호와 같은 무언가를 적용할 때 이것을 한 묶음으로 간주한다"라는 뜻이다. 따라서 텍스트에는 반드시 1이 나온 다음, 콤마에 이어 0이 세 개 따라붙는 묶음이 하나 이상 와야 하므로 "1,00,000"와 "1,000,00"은 일치하지 않는다.
+ 문자 다음에 오는 공백은 공백을 만났을 때 반드시 일치가 끝나야 함을 가리킨다. 공백이 없으면 "1,000,00"은 첫 "1,000"만 일치하고 나머지 ,00은 무시해서 올바르게 일치되지 않을 것이다. 나중에 오는 공백을 지정해야 숫자의 오른쪽 끝까지 일치가 계속 진행될 것이다.
문자 클래스
간혹 다소 불분명(fuzzy)하지만 점을 써야 할 만큼 광범위하지는 않은 것을 일치하고 싶을 때도 있다. 불분명하다는 건 정규 표현식의 가장 큰 강점인데, 정규 표현식에서는 정확함과 모호함을 원하는 만큼 조절할 수 있다.
퍼지 일치(fuzzy matching)를 지원하는 핵심 기능 중 하나는 바로 대괄호인 []이다. 대괄호는 점처럼 단일 문자를 일치하지만 대괄호 안에는 일치할 수 있는 대상의 목록을 집어넣을 수 있다. 텍스트에서 대괄호에 지정한 문자가 나타나면 해당 텍스트는 일치된 것이다. 예를 들어 미국식 철자인 "gray"와 영국식 철자인 "grey"를 모두 일치하고 싶다면 다음과 같이 패턴을 지정하면 된다.
/gr[ae]y/
일치 대상 텍스트에서는 gr이 나온 후에 a이나 e가 나올 수 있다. 하지만 둘 중 하나만 나와야 하는데, 대괄호에 무엇을 집어넣든 정확히 한 문자와 일치하기 때문이다. 대괄호 안에 든 문자 그룹을 문자 클래스(character class)라 한다.
범위 나타내기
대괄호 안에서는 하이픈(-)을 써서 범위를 나타낼 수 있다. 흔히 하는 작업 중 하나는 숫자 하나를 일치하는 것인데, 다음과 같은 방법으로 범위를 지정해서 일치할 수 있다.
/[0-9]/
숫자는 정규 표현식에서 공통적인 항목이라 숫자 표현을 위해 d라는 문자를 제공한다. 따라서 대괄호로 감싼 정규 표현식에 다음과 같이 d를 써서 숫자를 일치할 수 있다.
/d/
부정
대괄호에서 쓸 수 있는 또 하나의 중요한 기능은 문자 클래스의 부정이다. 여는 괄호 다음에 캐럿(^)을 지정해서 문자 클래스 전체를 뒤집을 수 있다. 이 말은 "다음에 나오는 것을 제외하고 어떠한 문자와도 일치한다."라는 뜻이다. "Yahoo" 다음에 느낌표가 없는 문자열을 찾는다고 가정해 보자. (이 회사의 공식 명칭에는 느낌표가 있다!) 이 경우 다음과 같은 패턴을 쓰면 된다.
/Yahoo[^!]/
단일 문자(느낌표)로 구성돼 있는 문자 클래스를 ^로 시작해서 뒤집었다. 이 방법은 실제로 문제를 해결하는 가장 좋은 방법은 아니다. 예를 들면 "Yahoo"가 한 줄의 끝에 나오면 이 방법은 통하지 않는다. 그 까닭은 해당 문자열 다음에 아무것도 나오지 않아 대괄호가 아무런 문자도 일치하지 못하기 때문이다. 더 나은 해법은 부정형 전방참조(negative look-ahead, 이어서 나오는 텍스트가 조건에 일치하지 않으면 일치함)를 쓰는 것이지만, 해당 주제는 기사의 범위를 벗어나므로 여기서 다루지는 않겠다.
더 복잡한 예제
문자 클래스와 부정을 이해하면 이제 HTML 태그의 일치 문제를 해결할 더 나은 해법을 시도해 볼 준비가 됐다. 이 해법은 단일 태그의 끝을 지나가지 않지만 <em>과 </em>을 비롯해 아래처럼 속성이 포함된 태그도 일치한다.
<a href="www.mozilla.org">
해법은 다음과 같다.
/<[^>]+>/
이 정규 표현식이 아무렇게 입력한 것처럼 보여도 완벽히 유효하면서도 매우 유용한 표현식이다. 이 정규 표현식을 여러 부분으로 쪼개보자. 각 요소는 다음과 같다.
- / - 정규 표현식을 나타내는 여는 슬래시.
- < - HTML 태그의 여는 괄호. 이 괄호는 일치 대상이며, 메타문자가 아니다.
- [^>] - 문자 클래스. ^>는 "닫는 괄호를 제외한 모든 문자와 일치한다"라는 뜻이다.
- + - 이전 패턴인 [^>]와 일치하는 문자가 하나라도 있으면 임의 개수의 문자와 일치한다.
- > - HTML 태그의 닫는 괄호. 이 문자는 일치 대상이다.
- / - 정규 표현식의 끝을 나타내는 닫는 슬래시.
이번에는 흔히 쓰는 정규 표현식을 하나 살펴보자.
/[^a-zA-Z0-9_]/
위 정규 표현식에는 또 다른 두 가지 중요한 메타문자가 있다. 두 메타문자는 정규 표현식이 특정 위치에 나타나게 하여 정규 표현식의 위치를 지정한다. 캐럿(^)이 정규 표현식이 시작할 때 나타나면, 해당 표현식은 한 줄이 시작하는 위치에 나와야 한다. 그렇지 않으면 일치하지 않는다. 이와 비슷하게 달러 기호($)가 정규 표현식의 끝에 나타나면 해당 표현식은 한 줄의 끝에 나와야 한다.
이제 기초적인 정규 표현식 맛보기는 다음과 같은 질문에 답하면서 마무리하겠다. 한 줄에 정규 표현식 외에는 아무것도 없게 만들고 싶다면? 한 줄에 "Le Guin" 말고는 아무것도 없게 만들고 싶다면? 이전 정규 표현식에 처음과 끝을 나타내는 부분을 추가하면 이렇게 할 수 있다.
/^Le *Guin$/
메타문자 요약
다음은 정규 표현식에서 사용 가능한 메타문자를 보여준다.
- / - 정규 표현식을 시작하고 끝낸다.
- . - 줄 바꿈 문자를 제외한 임의의 한 문자와 일치한다.
- element* - 요소와 0번 이상 일치한다.
- element+ - 요소와 1번 이상 일치한다.
- element? - 요소와 일치하지 않거나 한 번 일치한다.
- [characters] - 대괄호 안에 포함된 한 문자와 일치한다.
- [^characters] - 대괄호 안에 포함되어 있지 않은 한 문자와 일치한다.
- (regex) - regex를 그룹으로 간주하여 갯수를 세거나, 다음에 오는 *, +, ?에 적용한다.
- left|right - left나 right와 일치한다.
- l-r - l과 r사이의 문자 범위와 일치한다(대괄호 안에 있을 때만)
- ^ - 일치하는 패턴이 문자열의 처음에 있어야 함
- $ - 일치하는 패턴이 문자열의 끝에 있어야 함
- b - 단어의 경계와 일치한다.
- B - 단어의 경계가 아닌 문자와 일치한다.
- d - 숫자 문자 하나와 일치한다.
- D - 숫자 문자가 아닌 문자와 일치한다.
- n - 줄 바꿈 문자와 일치한다.
- s - 공백 문자와 일치한다.
- S - 공백 문자가 아닌 문자와 일치한다.
- t - 탭 문자와 일치한다.
- w - 단어 문자(a-z, A-Z, 0-9, _)와 일치한다
- W - 비단어 문자(a-z, A-Z, 0-9, _이 아닌 문자)와 일치한다
- x - x(x가 메타문자이더라도 x를 쓰고자 할 때 유용함)
- {n} - 정확히 n번 일치한다.
- {n,} - n번이나 그 이상 일치한다.
- {min,max} - 최소 min, 최대 max 번 일치한다.
위에서 설명한 내용을 바탕으로 /[^a-zA-Z0-9_]/라는 정규 표현식을 다시 한번 살펴보면, 이 표현식을 /[^w]/으로 줄여 쓸 수 있음을 알 수 있다. 이는 단일 메타문자인 w(소문자 w)가 a-Z, A-Z, 0-9, _를 나타내기 때문이다.
사실 앞의 정규 표현식을 더 명확하게 표현할 수도 있는데, 메타문자 W (대문자 W)가 a-Z, A-Z, 0-9, _를 제외한 모든 문자를 나타내기 때문이다. 따라서 ^ 메타문자를 빼고 단순히 /[W]/로 쓸 수도 있다. 이 정규 표현식이 어떻게 동작하는지 알려주기 위해 아래에 다양한 표현식과 그와 일치하는 패턴을 나열하였다.
- r - The quick brown에서 첫 r
- rec[ei][ei]ve - receive나 recieve (receeve나 reciive도 일치함)
- rec[ei]{2}ve - receive나 recieve (receeve나 reciive도 일치함)
- rec(ei)|(ie)ve - receive나 recieve (receeve나 reciive는 일치하지 않음)
- cat - I like cats and dogs에서 cat 단어
- cat|dog - I like cats and dogs에서 cat이나 dog라는 단어
- . - . (.가 메타문자이므로 가 필요함)
- 5.0* - 5., 5.0, 5.00, 5.000, 등
- a-f - a, b, c, d, e, f 중 문자 하나
- cats$ - My cats are friendly cats에서 마지막 cats
- ^my - my cats are my pets에서 첫 my만
- d{2,3} - 둘 또는 세 개의 숫자 (00에서 999까지)
- 7(,000)+ - 7,000, 7,000,000, 7,000,000,000, 7,000,000,000,000 등
- [w]+ - 하나 이상의 문자로 이루어진 단어
- [w]{5} - 임의의 5글자로 이루어진 단어
일반적인 변경자
정규 표현식에서는 몇 가지 변경자(modifier)를 사용할 수 있다.
- /g - "전역" 일치를 활성화. 바꾸기(replace) 기능을 쓸 경우 이 변경자를 쓰면 첫 번째 일치 결과만 바꾸는 것이 아니라 모든 일치 결과를 바꾼다.
- /i - 정규 표현식이 대소문자를 구별하지 않음. 따라서 /[a-zA-Z]/ 대신 /[a-z]/i나 [A-Z]/i를 지정하면 된다.
- /m - 캐럿(^)과 달러 기호($)가 대상 문자열 안의 줄 바꿈 전과 후와 일치하는 경우, 여러 줄 모드(multi-line mode)를 활성화. 보통 여러 줄 문자열에서 ^는 문자열의 시작과 일치하고, $는 문자열의 끝과 일치한다.
예를 들어, /cats/g라는 표현식은 "I like cats and cats like me"라는 문장에서 "cats"가 나타나는 곳과 모두 일치할 것이다. 이와 비슷하게, /dogs/gi라는 패턴은 "Dogs like other dogs"라는 문장에서 "dogs"("Dogs"와 "dogs")가 나타나는 곳과 모두 일치하는데, 이는 이러한 변경자를 함께 쓸 수 있기 때문이다.
자바스크립트에서 정규 표현식 사용하기
자바스크립트에서는 주로 test(이미 본 적이 있을 것이다)와 replace라는 메서드에서 정규 표현식을 쓸 것이다. test 메서드가 단지 전달한 인자와 정규 표현식의 일치 여부를 알려주는 데 반해, replace 메서드는 일치하는 텍스트를 대체할 문자열을 나타내는 두 번째 매개변수를 취한다. 대부분의 함수와 비슷하게 replace 메서드는 새로운 문자열을 반환값으로 생성하므로 입력된 문자열을 변경하지 않는다.
두 메서드를 비교하는 차원에서 아래 문장을 살펴보자. 아래 문장은 "cats"라는 단어가 전달한 문자열의 어딘가에 적어도 한번 나타나면 true를 반환한다.
document.write(/cats/i.test("Cats are fun. I like cats."))
하지만 다음 문장은 "cats"가 나타나는 곳을 "dogs"로 바꾸고 그 결과를 출력한다. 검색은 전역적으로(/g) 이루어져 모든 단어가 출현하는 곳을 찾고, 대소문자를 구별하지 않으므로(/i) 대문자로 쓴 "Cats"도 찾는다.
document.write("Cats are fun. I like cats.".replace(/cats/gi,"dogs"))
위 문장을 실행하면 replace의 한계를 확인할 수 있다. replace는 문자열을 정확히 사용하려고 하는 문자열로 바꾸기 때문에 첫 단어인 "Cats"는 "Dogs"가 아닌 "dogs"로 바뀐다.
PHP에서 정규 표현식 사용하기
PHP에서 쓸 법한 가장 널리 쓰는 정규 표현식 함수는 preg_match, preg_match_all, preg_replace이다.
어떤 문자열에서 대소문자를 구별하지 않고 "cats"라는 단어가 나타나는지 검사하려면 아래처럼 preg_match를 쓰면 된다.
$n = preg_match("/cats/i", "Cats are fun. I like cats.");
PHP에서는 1을 TRUE로, 0을 FALSE로 사용하므로 이전 문장에서는 $n이 1로 설정된다. 첫 인자는 정규 표현식이고 둘째 인자는 일치할 텍스트이다. 하지만 preg_match는 실제로 더 강력하고 복잡한데, 이 함수는 일치할 텍스트를 나타내는 셋째 인자를 받기 때문이다.
$n = preg_match("/cats/i", "Cats are fun. I like cats.", $match); echo "$n Matches: $match[0]";
셋째 인자는 배열(여기서는 $match)이다. 이 함수는 일치하는 텍스트를 첫 요소로 넣으므로 만약 일치가 성공하면 $match[0]에서 일치된 텍스트를 확인할 수 있다. 이 예제에서는 출력 결과를 통해 일치된 텍스트가 대문자로 시작함을 알 수 있다.
1 Matches: Cats
일치 위치를 모두 확인하고 싶다면 아래처럼 preg_match_all 함수를 쓰면 된다.
$n = preg_match_all("/cats/i", "Cats are fun. I like cats.", $match); echo "$n Matches: "; for ($j=0 ; $j < $n ; ++$j) echo $match[0][$j]." ";
전과 마찬가지로 $match를 함수에 전달했으며, $match[0]에는 일치된 결과가 할당되는데, 이번에는 2차원 배열의 부배열(sub-array)로 할당된다. 이 예제에서는 부배열을 보여주기 위해 for 루프를 이용해서 배열을 순회하였다.
문자열의 일부를 바꾸고 싶으면 아래처럼 preg_replace를 쓰면 된다. 이 예제는 대소문자를 구별하지 않고 "cats"가 나타나는 곳을 모두 "dogs"으로 바꾼다.
echo preg_replace("/cats/i", "dogs", "Cats are fun. I like cats.");
심화 source : http://www.hanbit.co.kr/network/view.html?bi_id=1653
'■ 프론트엔드 ■ > JavaScript' 카테고리의 다른 글
selectbox와 쿠키 사용하기 (1) | 2016.03.23 |
---|---|
HTML Table을 엑셀로 내보내기 : Export to excel sheet on client side (11) | 2015.04.02 |
변수에 함수를 할당 (0) | 2014.05.09 |
window.open() 메서드 : 새 브라우저 창을 엽니다. (0) | 2014.05.07 |
폼데이터 - 팝업창에서 부모창으로 submit (0) | 2014.02.26 |