'IT/JAVA'에 해당되는 글 2건

  1. 2017.05.24 정규표현식(regexp)
  2. 2017.05.19 JAVA 정규표현식

2017.05.24 17:43 IT/JAVA

정규표현식(regexp)

정규표현식이란 텍스트(text)를 기술하기 위한 표현방식을 말합니다. 정규표현식은 텍스트를 탐색하거나 문자열을 조작하는데 있어서 강력한 문법을 제공하여 줍니다.


정규표현식은 주로 유닉스 시스템과 펄(perl)과 같은 언어에서 많이 사용 되어왔으며, 그 말은 유닉스 시스템과 펄은 문자열을 아주 쉽게 처리할 수 있다는 것을 의미합니다.


이러한 정규표현식이 J2SDK 1.4에 이르러서야 공식적으로 기본 Package로 제공되게 되었습니다. 

J2SDK 1.4이전에는 정규표현식을 이용하기 위하여는 Apache Jakarta 프로젝트의 Regexp와 같은 package를 많이 이용하였습니다.


1. 정규표현식의 문법


정규표현식이란 문자열 안에서의 일정한 패턴을 표현하기 위한 표현식을 말합니다. 이러한 표현식은 펄, 유닉스 시스템 그리고 자바에서 공통적으로 사용될 수 있습니다. 정규표현식을 자바언어에서 이용하기 전에 먼저 정규표현식을 표현하는 방법부터 자세히 알 필요가 있습니다.



문자열 안에서 hello 라는 말이 들어가 있는지, 혹은 숫자가 안에 들어가 있는지 알아보고자 할 경우에 사용됩니다. 

정규표현식을 잘 사용한다는 말은, 찾고자 하는 패턴에 대한표현을 여러 가지 특수문자들을 이용하여 잘 표기한다는 것을 의미합니다. 이러한 패턴을표기하기 위한 특수문자에 대하여 잘 알아보도록 하겠습니다.



1-1) ‘.’ 특수 문자.


‘.’ 특수 문자는 임의의 한 문자를 나타냅니다. 예를 들면, h.s 라는 패턴은 반드시 ‘h'로 시작하며 's'로 반드시 끝나는 단어를 의미합니다. 따라서 'his', 'hos' 등은 모두 해당 패턴에 일치하는 문자열이라고 말할 수 있습니다. 그러나’hs’와 같은 문자열은 패턴에일치하지 않습니다. 

그 이유는 ’.‘특수문자가 위치한 곳에는 반드시 한글자가 위치하여야 하기 때문입니다.


예)


패턴 일치하는 문자열


a.b acb , adb , azd 등


ab. abc , abd , abz 등


.bc abc , dbc , zbc 등



1-2) ‘*’ 특수문자.


‘*’ 특수문자는 바로 앞의 문자를 나타냅니다. ‘*’ 는 바로 앞의 문자가 없거나 하나 이상 반복한다는 의미를 뜻합니다. 만약 ‘a*' 라고 쓰여있는 패턴이 있다면, 'a', 'aa', 'aaa' 등이 가능합니다. ’*‘ 특수문자를 사용할 때 주의하여야 할 점은 패턴을 지정할 때 ’*‘ 앞에는 한 글자 이상의 단어가 반드시 와야 한다는 것입니다.


예)


패턴 일치하는 문자열


hello* hell , hello, helloo, hellooo 등


ab*c abc , abbc , abbbc, abbbbc 등


*d 불가능



1-3) '+' 특수문자


‘+’ 특수문자는 ‘*’특수문자와 흡사하지만, ‘*’특수문자와는 달리 반드시 하나 이상의 문자가 반복을 해야 한다는 것입니다. 

예를 들자면 ‘hello+' 라고 패턴을 지정 한다면 ’hello','helloo' , 'hellooo' 등 ‘+’특수문자 바로 앞의 문자는 반드시 하나이상 반복해야 합니다.


예)


패턴 일치하는 문자열


hello+ hello , helloo, hellooo, helloooo 등


ab+c abc , abbc , abbbc , abbbbc 등


+d 불가능



1-4) ‘?’ 특수문자


‘?’ 특수문자의 바로 앞의 문자가 하나가 있거나, 없거나 하는 것을 의미합니다. 

예를 들자면 ‘a?c' 라고 패턴을 지정한다면 'c' , 'ac' 중에서 하나를 의미하게 됩니다.


예)


패턴 일치하는 문자열


hello? hell, hello


try? tr, try



1-5) '^' 특수문자


‘^’ 특수문자는 문장의 처음을 나타냅니다. 예를 들어 ‘^Hello' 라고 작성된 패턴이 있다면 해당 패턴에 일치하기 위하여 문자열은 반드시 'Hello' 로 시작을 하여야 합니다.


예)


패턴 일치하는 문자열


^Hello Hello World

^The The pen


1-6) '$' 특수문자


‘$’ 특수문자는 문장의 끝을 나타냅니다. 예를 들어 ‘World$' 라고 작성된 패턴이 있다면 해당 패턴에 일치하기 위하여 문자열은 반드시 ’World'로 끝을 맺어야 합니다.


예)


패턴 일치하는 문자열


World$ Hello PHP World


PHP$ Start PHP



1-7) '[ ]' 특수문자


대괄호 ‘[ ]’ 특수문자의 의미는 괄호 안의 문자 중 일치하는 것을 찾고자 할 경우 사용합니다. 

예를 들자면 '[abc]' 라고 패턴을 작성하게 되면 문자열에 ‘a' 나 ’b' 혹은 ‘c' 등이있어야 합니다.


예)


패턴 일치하는 문자열


[abc] a, b, c, ab, abc 등


[a-z] 소문자가 포함된 모든 문자열


[A-Z] 대문자가 포함된 모든 문자열


[0-9] 숫자가 포함된 모든 문자열


^[a-zA-Z0-9] 숫자나 영문자로 시작되는 모든 문자열



1-8) ‘[ ]’ 특수문자 안에서의 ‘^’ 특수문자


대괄호 ‘[ ]’ 특수문자 안에서 ‘^’ 특수문자가 쓰이게 되면 ‘[ ]’ 특수문자 안에 있는 문


자와 일치하지 않는 문자열을 포함하고 있는 패턴을 의미 합니다. 즉 ‘[^abc]de’ 라고 패턴


을 작성하게 되면 'ade', 'bde', 'cde' 를 제외한 ‘.de' 패턴과 같은 의미가 됩니다.



예)


패턴 일치하는 문자열


[^abc]de dde, fde, zde 등


a[^0-9]c abc, acd, add 등



1-9) ‘{ }’ 특수문자


중괄호 ‘{ }' 특수문자는 ’{ }‘ 특수문자 앞의 문자나 문자열의 반복되는 개수를 말합니


다. 예를 들자면 'hel{2}o' 라는 패턴을 작성하게 되면 ’hello' 문자열이 문자열에 포함되어


있어야 됩니다.


예)


패턴 일치하는 문자열


gu{5}ggle guuuuugle


gu{3,}ggle


(u가 3개 이상)


guuuggle, guuuuggle, guuuuuggle 등


gu{2,4}ggle guuggle, guuuggle, guuuuggle



1-10) '( )' 특수문자


소괄호 ‘( )’ 특수문자는 ‘( )’ 특수문자 안의 글자들을 하나의 문자로 봅니다. 예를 들어


‘gu(gg){2}le’ 와 같은 패턴을 작성하게 되면 ‘guggggle' 문자열이 문자열에 포함되어 있어


야 됩니다.


예)


패턴 일치하는 문자열


(hello){3} hellohellohello, hey hellohellohello 등


(hello)* NULL, hello, hellohello, hellohello 등



1-11) ‘|’ 특수문자


패턴 안에서 OR연산을 사용할 때 사용합니다. 예를 들어 'hi|hello' 는 hi 나 hello 가 포


함되어있는 문자열을 의미합니다.


예)


패턴 일치하는 문자열


man|woman man , woman, manwoman , superman 등


left|right left, right, leftright 등



1-12) 문자 클래스( character class )


'[]' 특수문자 안에서 자주 사용되는 패턴들을 미리 키워드로 정의하여 놓은 것을 문자


클래스라고 합니다. 해당 문자 클래스를 J2SDK 1.4에서는 다르게 사용을 합니다. (문자 클


래스는 PHP와 같은 언어에서는 이용되지만 JAVA에서는 이용되지 않습니다. J2SDK 1.4의


예를 참고하십시요. )


패턴 문자 클래스 J2SDK 1.4의 예


[a-zA-Z]


(모든 영문자)


[[:alpha:]] \p{Alpha}


[0-9]


(숫자)


[[:digit:]] \p{Digit}


[a-zA-Z0-9]


(영문자와 숫자)


[[:alnum:]] \p{Alnum}


공백 [[:space:]] \p{Space}



1-13) 정규표현식에서 특수문자의 사용

1-12) 까지 말한 특수문자를 정규표현식의 패턴에서 사용하려면 해당 특수문자 앞에역 슬래시(‘\’)를 붙입니다. 물론 역 슬래시(‘\’)를 패턴에서 사용 하려면 역 슬래시를 2개 연속하여 써주어야 합니다.



2. J2SDK 1.4.x에서의 정규표현식 이용


J2SDK 1.4.x에서 정규표현식을 이용하기 위한 방법으로는 크게, java.lang.String class에 새롭게 추가된 메소드를 이용하는 방법과 java.util.regex 패키지를 이용하는 방법이 있습니다. 2가지 방법에 대하여 모두 알아보도록 하겠습니다.



2-1) String class에 새롭게 추가된 정규표현식 관련 메소드



메소드 이름 설명


boolean matches(String regex) 

문자열 안에 regex정규표현식과 일치하는 패턴이 있다면 true, 그렇지 않으면 false를 반환합니다.


String replaceAll(String regex,String replacement)


문자열 안에 regex정규표현식으로 일치하는 모든 부분을 replacement문자열로 치환한 결과를 반환합니다.


String replaceFirst(String regex,String replacement)


문자열 안에 regex정규표현식으로 일치하는 첫 부분을replacement문자열로 치환한 결과를 반환합니다.


String[] split(String regex) 

문자열 안에 regex정규표현식과 일치하는 부분을 기준으로 분할하여 배열로 반환합니다.



예제1) matches메소드의 사용


ReTest1.java


public class ReTest1{


public static void main(String args[]){


String msg1 = "hello world";


String regex1 = "hello";


String regex2 = "hello([a-z ]*)";


System.out.println(msg1.matches(regex1));


System.out.println(msg1.matches(regex2));


String msg2 = "hello world3";


String regex3 = "hello";


String regex4 = "hello([a-z ]*)";


System.out.println(msg2.matches(regex3));


System.out.println(msg2.matches(regex4));


String msg3 = "gooooooogle";


String regex5 = "goo*gle";


String regex6 = "google";


System.out.println(msg3.matches(regex5));


System.out.println(msg3.matches(regex6));


} // end main


} // end class


ReTest1.java에서 사용된 matches메소드는 J2SDK1.4.x이상에서만 사용할 수 있기 때문에 컴파일 시에는 반드시 “-source 1.4”옵션을 줘야 합니다. 


소스를 한 줄 한 줄 설명하도록 하겠습니다.


String msg1 = "hello world";


String regex1 = "hello";


String regex2 = "hello([a-z ]*)";


System.out.println(msg1.matches(regex1));


System.out.println(msg1.matches(regex2));


msg1 String형 변수에 “hello world”문자열을 지정한 후, String class가 가지고 있는 matches메소드의 인자로 regex1과 regex2를 넣어서 결과를 확인 해보면, 첫 번째 것은 false가 두 번째 것은 true가 나옵니다. 

regex1의 패턴은 hello라는 정확한 패턴을 찾는 것이기 때문에 false이며 regex2의 패턴은 hello로 시작되며, 그 후의 문자열은 소문자와 공백들로 이루어져 있다라는 의미이기 때문입니다.


String msg2 = "hello world3";


String regex3 = "hello";


String regex4 = "hello([a-z ]*)";


System.out.println(msg2.matches(regex3));


System.out.println(msg2.matches(regex4));


msg2 String형 변수에 “hello world3”이라는 문자열을 지정한 후, matches메소드에 인자로 regex3와 regex4에 지정된 패턴을 인자로 넣어서 일치되는지 확인하고 있습니다. 

이경우, “hello”로 정의 된 패턴은 “hello”와 정확히 일치하여야 하기 때문에 false가 나오며, “hello([a-z ]*)”로 정의된 패턴은 msg2안에 들어있는 문자열 3을 지정하지 않았기 때문에 false가 반홥됩니다.


String msg3 = "gooooooogle";


String regex5 = "goo*gle";


String regex6 = "google";


System.out.println(msg3.matches(regex5));


System.out.println(msg3.matches(regex6));


msg3 String형 변수에 "gooooooogle"이라는 문자열을 지정한 후 패턴이 일치하는지


보고 있습니다. regex5에 지정된 패턴 “goo*gle”은 goo로 시작하고 gle로 끝나는 모든 문


자열을 지칭하는 것이기 때문에 true가 반환되며, regex6에 지정된 패턴 “google”은 정확


하게 “google”과 일치해야 함으로 false가 반환되게 됩니다.



예제2) replaceAll 메소드의 사용


ReTest2.java


public class ReTest2{


public static void main(String args[]){


String msg = "gooooooogle goooogle gooogle goooogle";


String regex = "goo*gle";


System.out.println(msg.replaceAll(regex, "google"));


} // end main


} // end class


ReTest2.java의 내용을 한 줄 한 줄 설명하도록 하겠습니다.


String msg = "gooooooogle goooogle gooogle goooogle";


String regex = "goo*gle";


System.out.println(msg.replaceAll(regex, "google"));


String형 변수 msg에 문자열 "gooooooogle goooogle gooogle goooogle"을 지정한 후,


replaceAll메서드를 이용하여 regex패턴과 일치하는 내용을 “google”이라는 문자열로 치환한 후 결과를 출력하도록 합니다. 이때 regex패턴 “goo*gle”은 “goo”로 시작하고 “gle”로끝나는 부분을 의미함으로 “gooooooogle” 문자열도 “google”로, “goooogle”문자열도“google”로 “google”문자열도 “google”로 치환하게 됩니다.



예제3) replaceFirst 메소드의 사용


ReTest3.java


public class ReTest3{


public static void main(String args[]){


String msg = "gooooooogle goooogle gooogle goooogle";


String regex = "goo*gle";


System.out.println(msg.replaceFirst(regex, "google"));


} // end main


} // end class



replaceFirst메소드는 replaceAll 메소드의 사용방법과 흡사하지만, 패턴과 일치하는 첫번째 문자열만 치환을 한다는 것입니다. 즉 소스를 분석하면 다음과 같습니다.


String형 변수 msg에 문자열 "gooooooogle goooogle gooogle goooogle"을 지정한후, replaceFist메서드를 이용하여 regex패턴과 일치하는 첫번째 문자열을 “google”이라는 문자열로 치환한 후 결과를 출력하도록 합니다. 

이때 regex패턴 “goo*gle”은 “goo”로 시작하고 “gle”로 끝나는 부분을 의미함으로 “gooooooogle” 문자열이 “google”로 치환하게 됩니다


예제4) split메소드의 사용


ReTest4.java


public class ReTest4{


public static void main(String args[]){


String msg = "one--two**three";


String regex = "--|\\*\\*";


String[] ss = msg.split(regex);


for(int i = 0; i < ss.length; i++){


System.out.println(ss[i]);


}


} // end main


} // end class



ReTest4.java를 한 줄 한 줄 설명하도록 하겠습니다.


String msg = "one--two**three";


String regex = "--|\\*\\*";


String[] ss = msg.split(regex);


for(int i = 0; i < ss.length; i++){


System.out.println(ss[i]);


}


msg String변수에 "one--two**three" 문자열을 지정한 후, regex String변수에 “--|\\*\\*” 정규표현식을 지정하고 있습니다. 해당 정규 표현식의 의미는 “--“와 일치 하거나 “**”와 일치하는 문자열을 말합니다. 이때 “*”문자 앞에 “\\”이 사용된 의미는 “*”


문자가 정규표현식에서 이미 정의된 특수문자이기 때문입니다. 정규표현식에서 “*”문자를 특수문자가 아닌 일반 문자로 사용하기 위하여는 앞에 “\(역 슬래시)”가 붙어야 하는데 자바 문법에서는 큰따옴표 안에서 “\_____”문자의 표현은 “\\”로 해야 하기 때문에 “\\*”와같이 사용되었습니다.


split메소드에 regex변수를 지정하여 문자열을 나눠 배열로 나뉘게 됩니다. 이 경우, msg문자열에는 “--“문자열과 “**” 문자열을 기준으로 쪼개지면서 ss배열에는 3개의 원소가 지정되게 됩니다. 3개의 원소는 “one”, “two” 그리고 “three”값을 말합니다.


for 반복문을 이용하여 ss배열의 길이만큼 출력한 결과는 따라서 그림4)와 같이 나오게 되는 것입니다.



1-2) java.util.regex 패키지를 이용한 정규표현식의 처리


java.util.regex 패키지는 J2SDK1.4이후에 추가된 패키지입니다. java.util.regex패키지는 Matcher, Pattern 2가지 클래스와 PatternSyntaxException 예외로 구성되어져 있습니다. 즉, java.util.regex 패키지를 이용한다는 것은 위의 3가지 클래스를 이용하는 것을 의미합니다.


사용 예를 하나 들어보도록 하겠습니다.


예제) java.util.regex 패키지의 이용


ReTest5.java


import java.util.regex.*;


public class ReTest5{


public static void main(String[] args){


String str = "hello++world--hi++world";


String regex = "(\\+\\+)|(--)";


Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);


Matcher m = p.matcher(str);


while (m.find()){


System.out.println("Found '" + m.group(0) + "' at position " +


m.start(0));


}


}


}


ReTest5.java 소스를 보면, 

Pattern class의 static 메소드인 compile메소드에 regex문자열(패턴)을 인자로 넣어 Pattern객체를 할당 받는 것을 알 수 있습니다. 그 후에, Pattern class가 가지고 있는 static 메소드인 macher메소드의 인자로 str문자열을 집어넣어 Matcher 객체를 할당 받습니다. Matcher 객체는 complie메소드의 인자로 넣은 패턴과 macher메소드의 인자로 넣은 문자열과 일치하는 정보를 객체화 하고 있는 객체입니다.


Macher객체를 얻은 후에는 Macher class가 가지고 있는 메소드를 이용하여, str문자열에서 regex패턴과 일치하는 문자열의 위치 정보를 모두 출력하게 됩니다.

이때 일치하는 문자열이 없을 때까지 모두 뽑아내기 위하여는 find메소드를 이용하였으며, 정규패턴그룹 0번째에 일치하는 문자열을 발견하기 위하여는 group메소드를, 일치하는 위치 값을 출력하기 위하여는 start메소드가 이용되었습니다.


참고하세요.


정규표현식에서 중요한 것으로 정규패턴그룹이 여기에서 사용되었는데, 정규패턴 그룹을 간단하게 설명하면 아래와 같습니다.


- 정규 표현 그룹이란 왼쪽에서 우측으로 괄호를 세는 것으로써, 번호를 붙일 수 있게 됩니다. 예를 들어 정규 표현식 ((A)(B(C))) 가 있을 경우 4개의 그룹으로 분류됩니다. 0번 값은 패턴 전체를 나타나게 됩니다.


1 ((A)(B(C)))


2 (A)


3 (B(C))


4(C)



예제) 문자열에서 URL값만 뽑아내기


ReTest7.java


import java.util.regex.*;


public class ReTest7{


public static void main(String[] args){


String regex = "([\\p{Alnum}]+)://([a-z0-9.\\-&%=?:@~\\_]+)";


//String regex = "([[a-zA-Z0-9]]+)://([a-z0-9.\\-&%=?:@~\\_]+)";


String strHTML = " <h1>http://www.yahoo.co.kr </h1> hohoho http://carami.sarang.net http://linux-sarang.net";


Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);


Matcher m = p.matcher(strHTML);


while (m.find()){


System.out.println(m.group(0));


System.out.println(m.group(1));


System.out.println(m.group(2));


System.out.println("----------------");


}


}


}



ReTest7.java예제는 strHTML 문자열에 있는 내용 중 URL정보만을 뽑아서 출력하는 예제입니다. "([\\p{Alnum}]+)://([a-z0-9.\\-&%=?:@~\\_]+)” 와 같은 복잡한 패턴이이용된 것을 알 수가 있습니다.




예제) URL을 자동으로 링크 걸기


ReTest8.java


import java.util.regex.*;


public class ReTest8{


public static void main(String[] args){


String regex = "([\\p{Alnum}]+)://([a-z0-9.\\-&%=?:@~\\_]+)";


//String regex = "([[a-zA-Z0-9]]+)://([a-z0-9.\\-


&%=?:@~\\_]+)";


String strHTML = " <h1>http://www.yahoo.co.kr </h1> hohoho http://carami.sarang.net http://linux-sarang.net";


Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);


Matcher m = p.matcher(strHTML);


String s = m.replaceAll("<a href='http://$2'


target=_blank>http://$2</a>");


System.out.println(s);


}


}



ReTest8.java는 ReTest7.java를 약간 수정하였습니다. 

ReTest8.java 는 Matcher lass가 가지고 있는 replaceAll메소드를 이용하여 자동으로 링크를 걸어주고 있습니다.


String s = m.replaceAll("<a href='http://$2' target=_blank>http://$2</a>");


위의 문장에서 $2 라고 나온 부분은 정규패턴 그룹의 2번째 부분을 말합니다.


ReTest7.java에서 group(2)로 출력되는 결과를 말합니다.



------------------------------------------------------------------------------------------------------------


자바스크립트



1. 개념잡기


일반화 시킨 표현. 이것을 정규표현이라고 요약할 수 있을 것 같다.

다음의 과정을 너무 쉽다 생각말고 따라오길 바란다.


- 감잡기


"12354" -> 숫자

"asdfasf" -> 알파벳

두 가지의 간단정규표현을 만들었다. 실생활의 보기와 비추어보자.

"길이가 3인 이름!"

위의 표현은 길이를 표시하는 방법이 없다.

조금 더 발전시켜서 "알파벳{3}"이런식으로 길이를 표현할 수 있도록 한다. 그리고, "알파벳"란 것도 너무 길다 "알" 이라고 한 글자로 표현한다. 그러면 "길이가 3인 이름"은 "알{3}"으로 표시가 가능하다.

길이가 10인 숫자는 "수{10}"

길이가 1인 알파벳이 나오고 그 다음에 길이가 3인 숫자가 나오는 문자열 "알{1}수{3}" 얼핏이나마 감이 올 것이다.

"첫 글자는A, 그 다음은 아무 알파벳 5글자" -> "A알{5}"


- 조금 더


아이디는 대개 첫 글자는 영문이고 두 번째부터는 영문이나 숫자가 온다. 이것을 표현하기 위해선 이것 들 중에 하나란 의미를 갖는 새로운 표현이 필요하다.

"a,b,c,d 중에 하나" -> [abcd]

응용하면,

"알파벳이나, 숫자중 하나" -> [알수]

"[" 안에 있는 문자들의 순서는 의미가 없으며, 그 표현은 (클래스라고 한다.)

결국 한 글자를 말한다.

위에서 말한 "첫 글자는 영문, 두 번째 부터는 영문이나 숫자가 11자"를 표현하면, "알[알수]{11}".

그런데, 실제로 모든 아이디가 12자인 것은 아니다, 대개 4자부터 12자를 지원한다.

새로운 표현이 등장한다. "몇 자부터 몇 자"

"A가 3글자부터 12자" -> "A{3,12}"

"알파벳이나 숫자가 1자부터 100자" -> "[알수]{1,100}"

이제 아이디를 다시 정의하자.

"첫 글자는 영문, 영문이나 숫자가 3자부터 11자" -> "알[알수]{3,11}"



2. 표현식


지금 까지의 규칙에서 설명한 용어를 실제 정규표현에서 사용하는 표현으로 바꾸고, 다른 세부적인 옵션에 대해 알아보자.


\ : 다음의 글자가 특별한 문자임을 나타낸다. 때론, 그 다음 문자 자체를 의미하기도 한다.

보기를 들면, "\n"은 문자"\"과 문자"n" 두 글자와 매치되는 것을 의미하는 것이 아닌, 새줄(New Line)을 의미하며, "\\"은 첫 "\" 다음 문자인 "\" 자체를 의미한다. 즉, "\\"은 "\"과 매칭된다.


^ : 입력문자열의 맨 처음을 의미한다. (맨 첫 글자가 아니라, 맨 처음이란 문맥적 의미를 말한다. 아주 중요하다) 기본적으로 정규표현은 입력 문자열의 한 줄에만 적용된다. 하지만, 옵션에 따라 여러줄에 적용할 수도 있다. 그럴 경우에는 "^"는 "\n" 나 "\r" 다음의 위치를 의미한다.


$ : "^"는 반대로 입력 문자열의 맨 끝을 의미한다. 역시 여러줄에 정규표현이 적용될 경우에는 "\n"이나 "\r"의 앞의 위치를 의미한다.


* : 이 문자 앞의 표현이 0번내지 무한번 반복될 수 있음을 말한다.

보기를 들면, /a*/은 "a", "", "aaaa", "aaaaa"와 매칭된다.

(0번이상은 없어도 된다는 것을 의미한다.)


+ : *와 같지만, 0번이상이 아니라 1번이상이라는 점을 제외하곤 /*/와 같다.


? : 앞의 표현이 0번 또는 1번. /do(es)?/는 "do", "does"와 매칭된다.


{n} : 앞의 표현이 n은 음수가 아닌 정수이어야 하며, 앞의 표현이 n번 매치되는 것을 말한다.


{n,} : 앞의 표현이 n은 음수가 아닌 정수이어야 하며, n번 이상 매치되는 것을 말한다.


{n,m} : 앞의 표현이 n번 이상 부터 m번 이하까지 매칭되는 것을 말하며, /*/는 /{0,}/과 같으며, /+/는 /{1,}/과 /?/는 /{0,1}/으로 표현 가능하다.


. : "\n"을 제외한 한 글자를 뜻한다. 만일 모든 글자를 표현하고 싶다면("\n"마저도 합친) /[.\n]/을 사용하면 된다.


x|y : x 또는 y와 매칭된다. 보기를 들면, /z|food/는 "z" 또는 "food"와 매칭된다. /(z|f)ood/는 "zood" 또는 "food"와 매칭된다.

(참고로 괄호는 묶어준 것 이상의 의미가 있다.)


(패턴) : 해당 패턴과 매칭시키고, 그 부분을 특정 변수에 담는다.

그 변수 이름은 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" 부분과 매칭이 된다.


[xyz] : "["안에 있는 표현중 하나를 의미한다.


[^xyz] : "["안에 있는 표현을 제외한 것중 하나를 의미한다. "[^abc]"는 "plain"의 "p"때문에 매칭된다.


[a-z] : "a"부터 "z" 까지의 문자중 하나


[^a-z] : "a"부터 "z" 까지의 문자를 제외한 하나


\b : 단어의 경계(단어와 공백, "\n", "\r"의 사이)와 매칭된다. 보기를 들면, "er\b"는 "never"와는 매칭되지만, "verb"와는 매칭되지 않는다.


\B : 단어의 경계가 아닌 것과 매칭된다. "er\B"는 "verb"와는 매칭되지만, "never"와는 매칭되지 않는다.


\cx : Ctrl+x 키와 매칭된다. "\cc"는 Ctrl+C와 매칭된다. x의 범위는 [a-zA-Z]이며, 만일 이 이외의 문자를 사용한다면 "\c"는 "c"와 동일하다.


\d : [0-9]와 같다.


\D : [^0-9]와 같다. 참고로 대문자는 소문자의 반대 의미를 갖는다.


\f : 폼피드(form-feed) 문자를 의미하며, "\x0c"와 "\cL"과 동일하다.


\n : 새 줄(newline)를 의미하며, "\x0a"와 "\cJ"와 동일하다.


\r : 캐리지 리턴(carriage return)을 의미하며, "\x0d"와 "\cM"과 동일하다.


\t : 탭. "\x09", "\cI"과 동일


\v : 버티컬 탭. "\x0b", "\cK"과 동일


\s : 화이트스페이스를 의미한다. 화이트스페이스란 공백, 탭, 폼피드, 캐리지리턴등을 의미한다. [ \f\n\r\t\v]과 동일("\f"앞에 공백이 있다. 주의!)


\S : "[^ \f\n\r\t\v]"


\w : "_"를 포함한 일반적인 단어에 사용되는 문자를 말한다. "[A-Za-z0-9_]" 과 동일


\W : "[^A-Za-z0-9_]"


\xn : n은 2자리 16진수이며, 해당 16진수 코드와 매칭된다. "\x412"는 16진수 41은 "A"이기 때문에 "A2"와 매칭된다.


\num : 캡쳐한 매칭을 가리킨다(백레퍼런스, backreference).

"(.)\1"은 연속된 두개의 문자열을 의미한다.

\n : "\1"은 위에서 캡쳐한 매칭(backreference)를 가리킨다고 했는데, 만일 이 패턴앞에 어떠한 n개의 캡쳐한 표현이 있다면 백레퍼런스이지만, 그렇지 않은 경우에는 8진수로 간주하여 해당 코드의 문자와 매칭된다.


\un : n은 4자리 UNICODE 이다. "\u00A9"은 copyright 심볼인 "ⓒ"와 매칭된다.



greedy, non-greedy


? : 앞에서 설명했는데, 왜 또? 라고 생각할 것이다.

?은 문맥에 따라 특별한 의미를 갖는다.

패턴 "o*"는 "foooood"와 매칭된다. 당연하다! 하지만, "f"앞의 "o"와 매칭되는 것이 아니다!! "ooooo"와 매칭된 것이다. 즉, 기본으로 정규표현 매칭은 가장 큰 범위를 선택한다. 이것을 greedy하다고 한다.

하지만, 때론 작은 범위에 매칭시킬 필요가 있을 경우가 있다.

(이의 적절한 보기는 잠시 후에 나온다.) "o*?"가 방금 말한 non-greedy 매칭이다.

수량관련 문자인 "*", "+", "?", "{n}", "{n,}", "{n,m}" 다음에 "?"가 나오면 non-greedy 매칭이된다.

잠시, 위에서 "o*?"가 "o"와 매칭된다고 했는데 이상하게 생각한 분이 있었을 것이다. 맞다. "o*?"는 ""와 매칭되었다. "*"는 0개이상임을 잊어선 안된다. "o+?"가 "o"와 매칭된다.



4. 보기


- 웹 주소


"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+\1\b/


- 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


 


정규식 구문

정규식은 일반 문자(예: a에서 z)와 메타문자 로 알려진 특수 문자로 구성된 텍스트 패턴입니다. 패턴은 텍스트 본문을 검색할 때 일치하는 문자열을 하나 이상 설명합니다. 정규식은 검색되는 문자열과 일치하는 문자 패턴을 찾는 템플릿의 역할을 합니다.


일반적으로 볼 수 있는 몇 가지 정규식 예는 다음과 같습니다.


JScript VBScript 검색 /^\[ \t]*$/ "^\[ \t]*$" 빈 줄을 찾습니다.

/\d{2}-\d{5}/ "\d{2}-\d{5}" 2자리, 하이픈 및 5자리로 구성된 ID 번호를 찾습니다.

/<(.*)>.*<\/\1>/ "<(.*)>.*<\/\1>" HTML 태그를 찾습니다.


 


아래 표는 정규식 컨텍스트에 사용되는 모든 메타문자와 메타문자의 동작을 보여줍니다.


문자 설명 \ 그 다음 문자를 특수 문자, 리터럴, 역참조, 또는 8진수 이스케이프로 표시합니다. 예를 들어, "n"은 문자 "n"을 찾고 "\n"은 줄 바꿈 문자를 찾습니다. "\\" 시퀀스는 "\"를 찾고 "\("는 "("를 찾습니다.

^ 입력 문자열의 시작 위치를 찾습니다. Multiline 속성이 설정되어 있으면 ^는 '\n' 또는 '\r'앞의 위치를 찾습니다.

$ 입력 문자열의 끝 위치를 찾습니다. Multiline 속성이 설정되어 있으면 $는 '\n' 또는 'r'뒤의 위치를 찾습니다.

* 부분식의 선행 문자를 0개 이상 찾습니다. 예를 들어, "zo*"는 "z", "zoo" 등입니다. *는 {0,}와 같습니다.

+ 부분식의 선행 문자를 한 개 이상 찾습니다. 예를 들어, "zo+"는 "zo", "zoo" 등이지만 "z"는 아닙니다. +는 {1,}와 같습니다.

? 부분식의 선행 문자를 0개 또는 한 개 찾습니다. 예를 들어, "do(es)?"는 "do" 또는 "does"의 "do"를 찾습니다. ?는 {0,1}과 같습니다.

{ n } n 은 음이 아닌 정수입니다. 정확히 n 개 찾습니다. 예를 들어, "o{2}"는 "Bob"의 "o"는 찾지 않지만 "food"의 o 두 개는 찾습니다.

{ n ,} n 은 음이 아닌 정수입니다. 정확히 n 개 찾습니다. 예를 들어, "o{2}"는 "Bob"의 "o"는 찾지 않지만 "foooood"의 모든 o는 찾습니다. "o{1,}"는 "o+"와 같고, "o{0,}"는 "o*"와 같습니다.

{ n , m } m 과 n 은 음이 아닌 정수입니다. 여기서 m 은 n 보다 크거나 같습니다. 최소 n 개, 최대 m 개 찾습니다. 예를 들어, "o{1,3}"은 "fooooood"의 처음 세 개의 o를 찾습니다. "o{0,1}"은 "o?"와 같습니다. 쉼표와 숫자 사이에는 공백을 넣을 수 없습니다.

? 이 문자가 다른 한정 부호(*, +, ?, { n }, { n ,}, { n , m })의 바로 뒤에 나올 경우 일치 패턴은 제한적입니다. 기본값인 무제한 패턴은 가능한 많은 문자열을 찾는 데 반해 제한적인 패턴은 가능한 적은 문자열을 찾습니다. 예를 들어, "oooo" 문자열에서 "o+?"는 "o" 한 개만 찾고, "o+"는 모든 "o"를 찾습니다.

. "\n"을 제외한 모든 단일 문자를 찾습니다. "\n"을 포함한 모든 문자를 찾으려면 '[.\n]' 패턴을 사용하십시오.

( pattern ) pattern 을 찾아 검색한 문자열을 캡처합니다. 캡처한 문자열은 VBScript의 경우 SubMatches 컬렉션, Jscript의 경우 $0 ... $9 속성을 이용하여 결과로 나오는 Matches 컬렉션에서 추출할 수 있습니다. 괄호 문자인 ( )를 찾으려면 "\(" 또는 "\)"를 사용하십시오.

(?: pattern ) pattern 을 찾지만 검색한 문자열을 캡처하지 않습니다. 즉, 검색한 문자열을 나중에 사용할 수 있도록 저장하지 않는 비캡처 검색입니다. 이것은 패턴의 일부를 "or" 문자(|)로 묶을 때 유용합니다. 예를 들어, 'industr(?:y|ies)는 'industry|industries'보다 더 경제적인 식입니다.

(?= pattern ) 포함 예상 검색은 pattern 과 일치하는 문자열이 시작하는 위치에서 검색할 문자열을 찾습니다. 이것은 검색한 문자열을 나중에 사용할 수 있도록 캡처하지 않는 비캡처 검색입니다. 예를 들어, "Windows(?=95|98|NT|2000)"는 "Windows 2000"의 "Windows"는 찾지만 "Windows 3.1"의 "Windows"는 찾지 않습니다. 예상 검색은 검색할 문자열을 찾은 후 예상 검색 문자열을 구성하는 문자 다음부터가 아니라 마지막으로 검색한 문자열 바로 다음부터 찾기 시작합니다.

(?! pattern ) 제외 예상 검색은 pattern 과 일치하지 않는 문자열이 시작하는 위치에서 검색할 문자열을 찾습니다. 이것은 검색한 문자열을 나중에 사용할 수 있도록 캡처하지 않는 비캡처 검색입니다. 예를 들어, "Windows(?!95|98|NT|2000)"는 "Windows 3.1"의 "Windows"는 찾지만 "Windows 2000"의 "Windows"는 찾지 않습니다. 예상 검색은 검색할 문자열을 찾은 후 예상 검색 문자열을 구성하는 문자 다음부터가 아니라 마지막으로 검색한 문자열 바로 다음부터 찾기 시작합니다.

x | y x 또는 y 를 찾습니다. 예를 들어, "z|food"는 "z" 또는 "food"를 찾습니다. "(z|f)ood"는 "zood" 또는 "food"를 찾습니다.

[ xyz ] 문자 집합입니다. 괄호 안의 문자 중 하나를 찾습니다. 예를 들어, "[abc]"는 "plain"의 "a"를 찾습니다.

[^ xyz ] 제외 문자 집합입니다. 괄호 밖의 문자 중 하나를 찾습니다. 예를 들어, "[^abc]"는 "plain"의 "p"를 찾습니다.

[ a-z ] 문자 범위입니다. 지정한 범위 안의 문자를 찾습니다. 예를 들어, "[a-z]"는 "a"부터 "z" 사이의 모든 소문자를 찾습니다.

[^ a-z ] 제외 문자 범위입니다. 지정된 범위 밖의 문자를 찾습니다. 예를 들어, "[^a-z]"는 "a"부터 "z" 사이에 없는 모든 문자를 찾습니다.

\b 단어의 경계, 즉 단어와 공백 사이의 위치를 찾습니다. 예를 들어, "er\b"는 "never"의 "er"는 찾지만 "verb"의 "er"는 찾지 않습니다.

\B 단어의 비경계를 찾습니다. "er\B"는 "verb"의 "er"는 찾지만 "never"의 "er"는 찾지 않습니다.

\c x X 가 나타내는 제어 문자를 찾습니다. 예를 들어, \cM은 Control-M 즉, 캐리지 리턴 문자를 찾습니다. x 값은 A-Z 또는 a-z의 범위 안에 있어야 합니다. 그렇지 않으면 c는 리터럴 "c" 문자로 간주됩니다.

\d 숫자 문자를 찾습니다. [0-9]와 같습니다.

\D 비숫자 문자를 찾습니다. [^0-9]와 같습니다.

\f 폼피드 문자를 찾습니다. \x0c와 \cL과 같습니다.

\n 줄 바꿈 문자를 찾습니다. \x0a와 \cJ와 같습니다.

\r 캐리지 리턴 문자를 찾습니다. \x0d와 \cM과 같습니다.

\s 공백, 탭, 폼피드 등의 공백을 찾습니다. "[ \f\n\r\t\v]"와 같습니다.

\S 공백이 아닌 문자를 찾습니다. "[^ \f\n\r\t\v]"와 같습니다.

\t 탭 문자를 찾습니다. \x09와 \cI와 같습니다.

\v 수직 탭 문자를 찾습니다. \x0b와 \cK와 같습니다.

\w 밑줄을 포함한 모든 단어 문자를 찾습니다. "[A-Za-z0-9_]"와 같습니다.

\W 모든 비단어 문자를 찾습니다. "[^A-Za-z0-9_]"와 같습니다.

\x n n 을 찾습니다. 여기서 n 은 16진수 이스케이프 값입니다. 16진수 이스케이프 값은 정확히 두 자리여야 합니다. 예를 들어, '\x41'은 "A"를 찾고 '\x041'은 '\x04'와 "1"과 같습니다. 정규식에서 ASCII 코드를 사용할 수 있습니다.

\ num num 을 찾습니다. 여기서 num 은 양의 정수입니다. 캡처한 문자열에 대한 역참조입니다. 예를 들어, '(.)\1'은 연속적으로 나오는 동일한 문자 두 개를 찾습니다.

\ n 8진수 이스케이프 값이나 역참조를 나타냅니다. \ n 앞에 최소한 n개의 캡처된 부분식이 나왔다면 n 은 역참조입니다. 그렇지 않은 경우 n 이 0에서 7 사이의 8진수이면 n 은 8진수 이스케이프 값입니다.

\ nm 8진수 이스케이프 값이나 역참조를 나타냅니다. \ nm 앞에 최소한 nm개의 캡처된 부분식이 나왔다면 nm 은 역참조입니다. \ nm 앞에 최소한 n개의 캡처가 나왔다면 n 은 역참조이고 뒤에는 리터럴 m이 옵니다. 이 두 경우가 아닐 때 n과 m이 0에서 7 사이의 8진수이면 \ nm 은 8진수 이스케이프 값 nm을 찾습니다.

\ nml n 이 0에서 3 사이의 8진수이고 m 과 l 이 0에서 7 사이의 8진수면 8진수 이스케이프 값 nml 을 찾습니다.

\u n n 은 4 자리의 16진수로 표현된 유니코드 문자입니다. 예를 들어, \u00A9는 저작권 기호(ⓒ)를 찾습니다.



------------------------------------------------------------------------------------------------------------


오라클


정규 표현식을 이용한 SQL 구문의 개선


저자 - Alice Rischert


Oracle Database 10g의 정규 표현식 기능을 텍스트 데이터 처리를 위한 강력한 도구로 활용할 수 있습니다.


Oracle Database 10g에 추가된 새로운 기능을 이용하여 문자 데이터의 검색, 처리 능력을 극적으로 개선할 수 있습니다. 정규 표현식(regular expression)이라 불리는 이 기능은, 텍스트 패턴을 기술하기 위한 일종의 표기법으로, 이미 오래 전부터 다양한 프로그래밍 언어와 UNIX 유틸리티를 통해 지원되어 왔습니다.


오라클의 정규 표현식은 SQL 함수와 WHERE절 연산자의 형태로 제공됩니다. 정규 표현식에 익숙하지 않은 독자라면, 이 문서를 통해 전혀 새롭고 강력한 기능을 체험하실 수 있을 것입니다. 또 정규 표현식에 이미 친숙한 독자분들은, Oracle SQL 언어의 문맥에 이 기능을 적용하는 방법을 이해하는 기회로 활용하실 수 있습니다.


정규 표현식이란?


정규 표현식은 하나 또는 그 이상의 문자열과 메타문자(metacharacter)로 구성됩니다. 가장 단순한 형태의 정규 표현식은 cat과 같은 단 하나의 문자열로만 구성될 수 있습니다. 이 정규 표현식은 문자 c와 문자 a, 문자 t의 순서를 갖는 패턴 매치 문자열로 cat, location, catalog 등의 문자열과 매치됩니다. 메타문자는 정규 표현식을 구성하는 문자들을 처리하는 방법을 명시하기 위한 알고리즘을 제공합니다. 다양한 메타문자의 의미를 이해한다면, 정규 표현식이 텍스트 데이터를 비교하고 대체하는 용도로 매우 유용하게 활용될 수 있음을 금방 깨닫게 되실 것입니다.


데이터의 검증, 중복 단어의 확인, 불필요한 공백의 제거, 문자의 파싱(parsing) 등 정규 표현식의 활용 방법은 실로 다양합니다. 정규 표현식을 이용하여 전화 번호, 우편 번호, 이메일 주소, 주민등록번호, IP 주소, 파일 이름, 경로 이름 등을 검증할 수도 있습니다. 또 HTML 태그, 숫자, 날짜, 기타 특정 텍스트 데이터와 일치하는 패턴을 확인하고 다른 패턴으로 대체하는 것이 가능합니다.


Oracle Database 10g에서 정규 표현식 사용하기


오라클에 새로 추가된 기능으로 Oracle SQL REGEXP_LIKE 연산자, REGEXP_INSTR, REGEXP_SUBSTR, REGEXP_REPLACE 함수 등이 있습니다. 이 함수와 연산자는 기존의 LIKE 연산자와 INSTR, SUBSTR, REPLACE 함수를 보완하는 효과를 제공합니다. 실제로 새로운 기능들은 기존 연산자 및 함수와 유사하지만 훨씬 강력한 패턴 매칭 환경을 구현하고 있습니다. 검색의 기준이 되는 데이터는 간단한 문자열일 수도 있고 데이터베이스 테이블의 문자 컬럼에 저장된 대량의 텍스트일 수도 있습니다. 정규 표현식을 이용하면 이전에는 생각도 못했던 유연한 방법으로 데이터를 검색, 대체, 검증할 수 있습니다.


정규 표현식의 기본적 예제


새로운 기능을 사용해 보기기 전에, 몇 가지 메타문자의 의미를 이해해 보기로 합시다. 마침표(.)는 정규 표현식에 존재하는 모든 문자(newline 제외)와 매칭됩니다. 예를 들어 정규 표현식 a.b는 문자 a, (newline을 제외한) 임의의 단일 문자, 그리고 문자 b의 순서로 구성된 문자열과 매칭됩니다. 문자열 axb, xaybx, abba는 모두 이 정규표현식에 정의된 패턴을 포함하고 있으므로 매치가 가능합니다. 라인이 a로 시작하여 b로 끝나는, 3 개 문자로 구성된 문자열을 매칭하고자 하는 경우에는 앵커(anchor)가 사용되어야 합니다. 캐럿(^) 메타문자는 라인의 시작을, 달러($) 기호는 라인의 끝을 의미합니다 (표 1 참고). 따라서 정규 표현식 ^a.b$는 aab, abb, axb와 같은 문자열과 매칭됩니다. LIKE 연산자에서 이와 동일한 기능을 수행하려면 a_b 패턴을 사용해야 합니다. 여기서 밑줄 기호(_)는 단문자 와일드카드를 의미합니다.


기본적으로, 정규 표현식의 개별 문자 또는 문자 리스트는 단 한 번만 매칭됩니다. 정규 표현식은 문자가 여러 번 반복 출현되는 조건을 지정하기 위한? 반복 연산자(repetition operator)를 제공합니다("quantifier"라 부르기도 합니다). 문자 a로 시작해서 b로 끝나는 문자열 매칭을 위한 정규 표현식이 아래와 같습니다: ^a.*b$. * 메타문자는 임의의 메타문자(.)가 0 번, 한 번, 또는 여러 번 반복되는 조건에 매칭됩니다. LIKE 연산자에서는 이와 동일한 연산자로 a%b를 지원합니다. 여기서 퍼센트(%) 기호는 임의 문자가 0 번, 한 번, 또는 여러 번 반복됨을 의미합니다.


표 2는 반복 연산자의 전체 목록을 보여 주고 있습니다. 이 표에 제시된 예를 통해 정규 표현식이 기존의 LIKE와일드카드 문자보다 훨씬 뛰어난 유연성을 제공함을 확인할 수 있습니다. 표현식에 괄호를 씌우는 경우, 서브표현식(subexpression)으로 활용됩니다. 서브표현식은 임의의 횟수만큼 반복될 수 있습니다. 예를 들어, 정규 표현식 b(an)*a는 ba, bana, banana, yourbananasplit등과 매치됩니다.


오라클의 정규 표현식은 POSIX(Portable Operating System Interface) 문자 클래스를 지원합니다(표 3 참고). 따라서 검색하는 문자의 유형을 세부적으로 정의하는 것이 가능합니다. 알파벳이 아닌 문자를 검색하는 조건을 LIKE 연산자로 작성한다면, WHERE 절이 훨씬 복잡한 형태로 구현되어야 할 것입니다.


POSIX 문자 클래스는 반드시 대괄호([])로 묶여 져야 합니다. 예를 들어, 정규 표현식 [[:lower:]]는 소문자와 매치되며 d [[:lower:]]{5}는 5 개의 연속적인 소문자와 매치됩니다.


POSIX 문자 클래스와 별도로, 개별 문자를 문자 리스트(character list)에 포함시키는 기능이 제공됩니다. 예를 들어 정규 표현식 ^ab[cd]ef$는 문자열 abcef , abdef와 매치됩니다. 여기서 c 또는 d 두 개의 문자 중 하나가 사용되고 있어야 합니다.


문자 리스트 내부에 위치하는 대부분의 메타문자는 일반 문자로 인식됩니다. 그 예외가 캐럿 (^) 기호와 하이픈 (-)기호입니다. 일부 메타문자는 문맥에 따라 다른 의미를 갖습니다. 이 때문에 정규 표현식이 무척 복잡해 보일 수도 있습니다. 캐럿 ^이 그 한 가지 예입니다. 이 기호를 문자 리스트의 첫 번째 문자로 사용되는 경우에는, 문자 리스트의 반대 조건(negation)을 의미합니다. 따라서[^[:digit:]]은 숫자가 아닌 문자로 구성된 패턴과 매칭되는 반면 ^[[:digit:]] 은 숫자로 시작되는 패턴과 매칭됩니다. 하이픈 (-)은 영역(range)을 의미합니다. 정규 표현식 [a-m]은 a와 m 사이의 임의의 문자와 매칭됩니다. 하지만 [-afg]의 경우처럼 하이픈이 문자 리스트의 첫 번째 문자로 사용된 경우에는 실제 하이픈 문자를 의미합니다


앞에서 괄호를 사용하여 서브표현식을 구현하는 방법을 예시한 바 있습니다. 서브표현식에서는 수직 기호(|)메타문자를 사용하여 여러 개의 대체 문자를 지정할 수 있습니다.


예를 들어, 정규 표현식 t(a|e|i)n은 문자 t와 n 사이에 오는 3 개의 대체 문자를 지정하고 있습니다. tan, ten, tin, Pakistan 등의 문자열은 매치되지만 teen, mountain, tune 등은 매치되지 않습니다. 또 정규 표현식 t(a|e|i)n을 문자 리스트 t[aei]n으로 표현할 수도 있습니다. 표 4는 이러한 메타문자들을 요약하고 있습니다. 지금까지 설명한 것 말고도 다양한 메타문자가 있지만, 여기에서는 본 문서에서 예제로 사용되는 정규 표현식을 이해할 수 있는 정도만 이해하고 넘어가기로 합니다.


REGEXP_LIKE연산자


REGEXP_LIKE오라클 데이터베이스에 적용 가능한 정규 표현식 기능을 제공합니다. 표 5는 REGEXP_LIKE의 문법을 보여주고 있습니다


아래 SQL 쿼리의 WHERE 절에서 사용된 REGEXP_LIKE 연산자는 정규 표현식 [^[:digit:]]을 만족하는 패턴의 ZIP 컬럼을 검색하고 있습니다. 이 조건절을 이용하여, ZIPCODE 테이블로부터 숫자가 아닌 문자를 포함하는 ZIP 컬럼이 포함된 모든 로우를 가져올 수 있습니다.


SELECT zip

FROM zipcode

WHERE REGEXP_LIKE(zip, '[^[:digit:]]')

ZIP

-----

ab123

123xy

007ab

abcxy


이 정규 표현식은 메타문자, 좀 더 정확히 말하면 콜론과 대괄호로 묶인 POSIX 문자 클래스 digit만을 사용하고 있습니다. [^[:digit:]]에서 두 번째로 사용된 대괄호는 문자 클래스 리스트를 묶는 용도로 사용됩니다. 앞에서 설명한 것처럼 POSIX는 문자 리스트를 구성하는 용도로만 사용되므로 이와 같은 처리가 필요합니다.


REGEXP_INSTR 함수


이 함수는 패턴의 시작 위치를 반환하며, 따라서 INSTR 함수와 유사한 형태로 동작합니다. REGEXP_INSTR함수의 사옹 방법은 표 6에서 확인할 수 있습니다. 두 함수의 가장 중요한 차이는 REGEXP_INSTR를 이용하는 경우 특정 문자열이 아닌 패턴을 지정할 수 있으며, 따라서 훨씬 유연한 검색이 가능하다는 사실입니다. 다음 예에서는 REGEXP_INSTR을 사용하여 Joe Smith, 10045 Berry Lane, San Joseph, CA 91234문자열에서 5 개의 숫자로 구성된 우편 번호 패턴의 시작 부분을 반환하고 있습니다. 정규 표현식 [[:digit:]]{5}를 사용하는 경우 우편 번호가 아닌 집 주소 번호의 시작 위치를 얻게 됩니다 (처음으로 검색되는 5 개 연속 숫자 패턴이 10045이기 때문입니다). 따라서 $ 메타문자를 사용하여 표현식의 앵커를 라인 끝부분으로 지정해야 합니다. 이렇게 하면 집 주소 번호에 관계없이 우편 번호의 시작 위치를 얻을 수 있습니다.


SELECT REGEXP_INSTR('Joe Smith, 10045 Berry Lane, San Joseph, CA 91234',

'[[:digit:]]{5}$')

AS rx_instr

FROM dual

RX_INSTR

---------- 

45


좀 더 복잡한 패턴의 작성


앞의 예의 우편 번호 패턴을 확장하여 네 가지 숫자를 포함하는 패턴을 만들어 보기로 합시다. 새로 작성된 패턴이 아래와 같습니다:


[[:digit:]]{5}(-[[:digit:]]{4})?$.


소스 문자열이 5 개 숫자로 종료되든, 또는 "5 개 숫자 + 4 자리 우편 번호" 포맷을 갖든, 패턴의 시작 위치를 얻을 수 있습니다.


SELECT REGEXP_INSTR('Joe Smith, 10045 Berry Lane, San Joseph, CA 91234-1234',

' [[:digit:]]{5}(-[[:digit:]]{4})?$')

AS starts_at

FROM dual

STARTS_AT

----------

44


위의 예에서 괄호로 묶인 서브표현식 (-[[:digit:]]{4})는 반복 연산자 ?로 지정된 조건에 따라 0 회 또는 1 회 반복됩니다. 다시 말하지만, 기존의 SQL 함수를 이용하여 같은 결과를 얻어 내려면 아무리 SQL 전문가라 해도 쉽지 않은 작업이 될 것입니다. 표 7은 정규 표현식을 구성하는 각 문자와 메타문자의 의미를 설명하고 있습니다.


REGEXP_SUBSTR함수


REGEXP_SUBSTR 함수는 SUBSTR 함수와 마찬가지로 문자열의 일부를 추출합니다. 표 8은 새로운 함수의 사용법을 설명하고 있습니다. 아래 예제에서는 [^,]*, 패턴에 매치되는 문자열이 반환됩니다. 정규 표현식은 공백에 이어 사용된 쉼표를 검색하고, 쉼표가 아닌 문자가 0 회 또는 그 이상 반복되는 패턴을 검색([^,]*)한 후 마지막으로 또 다른 쉼표를 검색합니다. 이 패턴은 쉼표로 구분된 문자열(comma-separated values)과 유사한 배열을 갖습니다.


SELECT REGEXP_SUBSTR('first field, second field , third field',

', [^,]*,')

FROM dual

REGEXP_SUBSTR('FIR

------------------

, second field ,


REGEXP_REPLACE 함수


특정 문자열을 다른 문자열로 대체하는 기존의 REPLACE SQL 함수의 기능을 잠시 되짚어 보겠습니다. 데이터의 텍스트에 필요 이상의 공백 기호가 존재하는 상황에서, 이를 단일 공백 기호로 대체하는 경우를 가정해 봅시다 REPLACE 함수를 사용할 때에는 대체할 공백 기호의 숫자를 정확하게 지정해야 합니다. 하지만, 필요 없는 공백의 수가 일정하리라는 보장은 없습니다. 아래 예는 Joe와 Smith사이에 3 개의 공백 기호가 존재하는 경우를 검색하고 있습니다. REPLACE 함수의 매개변수는 두 개의 공백 기호를 하나의 공백 기호로 대체할 것을 명시하고 있습니다. 하지만 Joe와 Smith 사이에 3 개의 공백 기호가 존재하는 경우에는 여전히 필요 없는 공백이 하나 남게 됩니다.


SELECT REPLACE('Joe Smith',' ', ' ')

AS replace

FROM dual

REPLACE

---------

Joe Smith


REGEXP_REPLACE 한층 개선된 문자열 대체 기능을 제공합니다. 그 사용법은 표 9에서 설명되고 있습니다. 아래 쿼리는 두 개 또는 그 이상의 공백 기호를 하나의 공백 기호로 대체합니다. ( )서브표현식은 하나의 공백 기호를 포함하며 {2,}의 조건에 의해 지정된 대로 2 회 또는 그 이상 반복되는 조건을 명시합니다.


SELECT REGEXP_REPLACE('Joe Smith',

'( ){2,}', ' ')

AS RX_REPLACE

FROM dual

RX_REPLACE

----------

Joe Smith


백레퍼런스(Backreference)


정규 표현식의 유용한 기능의 하나로 재활용을 위해 서브표현식을 저장하는 기능이 제공됩니다. 이 기능을 백레퍼런스(backreferencing)라 부릅니다(상세한 설명은 표 10 참고). 백레퍼런스를 이용하여 패턴을 새로운 위치에 맞교체하거나 반복적인 단어 또는 문자를 검색하는 등의 고급 대체 기능을 구현할 수 있습니다. 서브표현식과 일치하는 문자열은 임시 버퍼에 저장됩니다. 이 버퍼에는 왼쪽에서 오른쪽 순서로 숫자가 매겨지며 \digit 형태로 표현됩니다. 여기서 digit은 1과 9 사이의 숫자를 의미하며 각 숫자에 해당하는 서브표현식과 매치됩니다.


아래 예제는 서브익스프레션에 대한 백레퍼런스를 이용하여 Ellen Hildi Smith라는 이름을 Smith, Ellen Hildi로 변환하고 있습니다.


SELECT REGEXP_REPLACE(

'Ellen Hildi Smith',

'(.*) (.*) (.*)', '\3, \1 \2')

FROM dual

REGEXP_REPLACE('EL

------------------

Smith, Ellen Hildi


위의 SQL 구문은 각각 괄호로 묶인 3 개의 서브표현식을 사용하고 있습니다. 각 서브표현식은 임의의 단일 문자와 매치되는 메타문자(.)와, 임의의 문자(newline 제외)와 0 회 또는 그 이상 매치되는 * 메타문자를 연이어 사용하고 있습니다. 각 서브표현식 사이에 사용된 공백 기호 역시 매치되어야 합니다. 괄호로 묶인 서브표현식에 의해 캡처된 값은 \digit에 의해 참조할 수 있습니다. 따라서 첫 번째 서브표현식에는 \1이, 두 번째 표현식에는\2이 할당됩니다. 이 백레퍼런스들은 함수의 마지막 매개변수 (\3, \1 \2)로 사용되어, 서브문자열을 대체하고 (쉼표와 공백을 포함하는) 포맷으로 표현하는 용도로 활용되고 있습니다. 표 11은 정규 표현식의 개별 컴포넌트에 대한 상세 정보를 설명하고 있습니다.


백레퍼런스는 값을 대체, 포맷하는 용도로 유용하게 활용되며, 서로 인접한 값을 찾기 위해 이용할 수도 있습니다. 다음 예제는 REGEP_SUBSTR 함수를 이용하여 공백 기호로 구분된 알파벳/숫자 값의 중복 사례를 검색하고 있습니다. 이 함수가 반환된 서브문자열을 통해 is 문자열이 반복되고 있음을 알 수 있습니다.


SELECT REGEXP_SUBSTR(

'The final test is is the implementation',

'([[:alnum:]]+)([[:space:]]+)\1') AS substr

FROM dual

SUBSTR

------

is is


매치 매개변수 옵션


앞에서 예시한 예제들을 통해 정규 표현식 연산자와 함수에 매치 매개변수(match parameter)를 추가적으로 활용할 수 있음을 눈치 채셨을 것입니다. 이 매개변수는 대소문자 구분, newline 문자의 매치, 멀티라인 입력의 보존 등을 지원합니다.


정규 표현식의 활용 사례


Y정규 표현식은 단순 쿼리 이외에도 PL/SQL 언어처럼 SQL 연산자, 함수가 사용되는 경우라면 언제든 적용이 가능합니다. 또 정규 표현식을 이용하여 값의 검증, 생성, 추출을 위한 기능을 트리거 형태로 구현할 수 있습니다.


다음 예제는 입력된 데이터에 대해 컬럼 제약 조건을 검증하기 위해 REGEXP_LIKE 연산자를 사용하는 방법을 예시하고 있습니다. 이 쿼리는 INSERT, UPDATE 작업이 발생하는 경우 입력이 사회보장번호의 포맷과 일치하는지 확인합니다. 123-45-6789 또는 123456789과 같은 포맷으로 표현된 사회보장번호는 컬럼의 제약 조건을 만족합니다. 데이터는 3 개의 숫자로 시작하여 하이픈으로 연결된 후, 다시 두 개의 숫자, 하이픈, 마지막으로 4 개의 숫자로 표현됩니다. 또는 사회보장번호를 9 개의 연속적 숫자로 표현하는 것도 가능합니다. 수직 기호(|)는 두 가지 옵션 중 선택이 가능함을 의미합니다.


ALTER TABLE students

ADD CONSTRAINT stud_ssn_ck CHECK

(REGEXP_LIKE(ssn,

'^([[:digit:]]{3}-[[:digit:]]{2}-[[:digit:]]{4}|[[:digit:]]{9})$'))


^, $. 기호는 가장 앞에 또는 가장 뒤에 오는 문자를 무시할 것을 지정하고 있습니다. 정규 표현식이 두 개 이상의 라인으로 분절되거나 표현식에 불필요한 공백 기호가 포함되지 않도록 주의하시기 바랍니다. 표 12는 위 정규 표현식 예제에서 사용된 각각의 컴포넌트에 대해 설명하고 있습니다.


정규 표현식과 기존 SQL 기능의 비교


정규 표현식은 기존에 사용되던 LIKE 연산자와 INSTR, SUBSTR, and REPLACE 함수와 비교했을 때 여러 가지 이점을 제공하고 있습니다. 기존의 SQL 함수는 패턴 매칭을 전혀 지원하지 않고 있습니다. 문자의 매칭을 지원하는 컴포넌트는 LIKE연산자가 유일하며 % , _와일드카드 문자가 지원됩니다. 하지만 LIKE 연산자는 표현식의 반복, 복잡한 대체 패턴, 문자 영역, 문자 리스트, POSIX 문자 클래스 등을 지원하지 않습니다. 또 새로운 정규 표현식 함수는 반복 단어와 패턴의 맞교환(swap)을 지원한다는 장점이 있습니다. 본 문서에서 제시된 예제들이 정규 표현식의 개념과 활용 방법을 이해하는데 도움이 되었기 바랍니다.


툴킷 확장을 위한 유용한 도구


정규 표현식은 복잡한 문제의 해결을 가능하게 하는 매우 강력한 기능입니다. 정규 표현식은 기존 SQL 함수로는 흉내내기 어려운 다양한 기능을 지원합니다. 정규 표현식의 사용법이 다소 복잡해 보이기는 하지만, 그 기본적인 구성 요소만 익혀도 SQL뿐 아니라 다른 프로그래밍 언어에서도 유용한 도구로 활용하실 수 있을 것입니다. 원하는 패턴을 얻기 위해서는 여러 차례의 시행착오가 불가피할 수도 있습니다. 하지만 어느 누구도 정규 표현식의 우아함과 강력한 기능을 결코 무시할 수 없을 것입니다.


Alice Rischert (ar280@yahoo.com)는 콜럼비아 대학 컴퓨터 테크놀로지/애플리케이션 프로그램의 데이터베이스 애플리케이션 개발/설계 트랙 담당 회장입니다. 그녀는 <Oracle SQL Interactive Workbook 2nd edition(Prentice Hall, 2002)>과 조만간 출판 예정인 <Oracle SQL by Example(Prentice Hall, 2003)>의 저자이기도 합니다. Rischert 는 포춘 100대 기업에서 데이터베이스 설계, DBA, 프로젝트 리더로 15 년 간의 경력을 보유하고 있으며 오라클 데이터베이스는 버전 5부터 사용해 온 베테랑입니다.


표 1: 메타문자의 앵커(anchor) 적용


Metacharacter

설명


^

라인의 시작 부분에 표현식을 적용


$

라인의 끝부분에 표현식을 적용 


표 2: 반복 연산자(Repetition Operator, Quantifier)


Quantifier

설명


*

0 회 또는 그 이상 횟수로 매치


?

0 회 또는 1 회 매치


+

1 회 또는 그 이상 횟수로 매치


{m}

정확히 m 회 매치


{m,}

최소한 m 회 매치


{m, n}

최소 m 회, 최대 n 회 매치


표 3: 사전정의된 POSIX 문자 클래스


Character Class

설명


[:alpha:]

알파벳 문자


[:lower:]

소문자 알파벳 문자


[:upper:]

대문자 알파벳 문자


[:digit:]

숫자


[:alnum:]

알파벳/숫자


[:space:]

출력되지 않는 공백 문자(예: carriage return, newline, vertical tab, form feed 등


[:punct:]

구두점 기호


[:cntrl:]

(출력되지 않는) 컨트롤 문자


[:print:]

출력 가능한 문자


표 4: 대체 매칭 및 표현식의 그룹화


Metacharacter

설명


|

Alternation

대체 문자를 구분 (그룹핑 연산자 ()와 함께 사용하기도 함)


( )

Group

반복 연산자 또는 백레퍼런스(backreference)를 위해 대체 유닛을 서브표현식으로 그룹화 ("백레퍼런스" 섹션 참고)


[char]

Character list

I문자 리스트. 문자 리스트 내부에 위치하는 대부분의 메타문자는 일반 문자로 인식됨. 그 예외가 캐럿(^) 기호와 하이픈(-) 기호


표 5: REGEXP_LIKE 연산자


문법

설명


REGEXP_LIKE(source_string, pattern

[, match_parameter])

source_string은 문자 데이터타입 지원 (CHAR, VARCHAR2, CLOB, NCHAR, NVARCHAR2, NCLOB 단 LONG 은 제외). pattern매개변수는 정규 표현식을 참조하는 또 다른 이름. 옵션으로 제공되는 match_parameter를 이용하여 newline 문자의 처리, 멀티라인 포맷의 유지, 대소문자 구분 등을 처리할 수 있음.


표 6: REGEXP_INSTR 함수


문법

설명


REGEXP_INSTR(source_string, pattern

[, start_position

[, occurrence

[, return_option

[, match_parameter]]]])

pattern을 검색하여 패턴의 첫 번째 위치를 반환. 필요한 경우 start_position y을 이용하여 검색을 시작할 위치를 지정할 수 있음. occurrence매개변수는 같은 패턴을 여러 번 검색하고자 하는 경우에 사용(디폴트는 1). return_option은 패턴의 시작 위치를 반환(디폴트 값은 0). 1로 설정되는 경우 매치된 패턴의 다음 문자 위치를 반환.


표 7: 5 자리 숫자 + 4 자리 Zip-Code 표현식에 대한 설명


문법

설명


매치되어야 하는 빈 공백


[:digit:]

POSIX "numeric digit" 클래스 


]

문자 리스트(character list)의 끝


{5}

문자 리스트에 대해 정확히 5 회 반복


(

서브표현식(subexpression)의 시작 부분


-

하이픈(-) 문자 (문자 리스트 내의 range 메타문자로 사용되지 않았음에 주의)


[

문자 리스트의 시작 부분 


[:digit:]

POSIX [:digit:] 클래스 


[

문자 리스트의 시작 부분 


]

문자 리스트의 끝 부분 


{4}

문자 리스트를 정확히 4 회 반복


)

서브표현식을 묶는 괄호 기호 


?

? 반복 연산자는 그룹핑된 서브표현식을 0 회 또는 1 회 매치하여 옵션으로 4 자리 코드를 사용할 수 있게 함 


$

검색 위치를 라인의 끝부분으로 지정하기 위한 앵커 메타문자 


표 8: The REGEXP_SUBSTR 함수


문법

설명


REGEXP_SUBSTR(source_string, pattern

[, position [, occurrence

[, match_parameter]]])

REGEXP_SUBSTR 함수는 패턴애 매치되는 서브문자열을 반환.


표 9: TheREGEXP_REPLACE 함수


문법

설명


REGEXP_REPLACE(source_string, pattern

[, replace_string [, position

[,occurrence, [match_parameter]]]])

매치된 패턴을 지정된 replace_string으로 대체하고, 복잡한 검색/대체 작업을 가능하게 하는 함수.


표 10: 백레퍼런스 메타문자 (Backreference Metacharacter)


Metacharacter

설명


\digit

Backslash

백슬래시 뒤에 1-9 사이의 숫자를 명시하여, 괄호 처리된 N 번째 서브표현식을 참조하기 위해 사용.

(참고: 백슬래시는 정규 표현식에서 다른 의미로 사용되기도 함. 문맥에 따라 Escape 문자를 의미할 수도 있음.



표 11: 패턴-스왑(Pattern-Swap) 정규 표현식의 설명


정규 표현식 아이템

설명


(

첫 번째 서브표현식의 시작 


.

(newline을 제외한) 임의의 단일 문자와 매치


*

반복 연산자 - 앞의 . 메타문자와 0 회에서 n 회까지 매치 


)

첫 번째 서브표현식의 마지막. 매치 결과는 \1

에 캡처됨(예제에서는 Ellen을 캡처)


공백 기호 


(

두 번째 서브표현식의 시작 


.

newline을 제외한 임의의 단일 문자와 매치 


*

반복 연산자 - 앞의 . 메타문자와 0 회에서 n 회까지 매치 


)

두 번째 서브표현식의 마지막; 매치 결과는 \2

에 캡처됨(예제에서는 Hildi를 저장).


공백 기호 


(

세 번째 서브표현식의 시작 


.

newline을 제외한 임의의 단일 문자와 매치 


*

반복 연산자 - 앞의 . 메타문자와 0 회에서 n 회까지 매치 


)

세 번째 서브표현식의 끝 부분. 매치 결과는 \3

에 캡처(예제에서는 Smith를 저장).


표 12: Social Security Number 정규 표현식의 설명


정규 표현식 아이템

설명


^

라인 문자의 시작(정규 표현식은 매치되기 이전의 문자를 가져 올 수 없음.)


(

서브표현식을 시작하고 | 메타문자를 이용하여 대체 목록을 제공


[

문자 리스트(character list)의 시작


[:digit:]

POSIX "numeric digit" 클래스 


]

문자 리스트의 끝 부분 


{3}

문자 리스트를 정확하게 3 회 반복 적용


-

하이픈 


[

문자 리스트의 시작 


[:digit:]

POSIX numeric digit 클래스 


]

문자 리스트의 끝 부분 


{2}

문자 리스트를 정확하게 2 회 반복 적용


-

또 다른 하이픈 기호 


[

문자 리스트의 시작 


[:digit:]

POSIX numeric digit 클래스 


]

문자 리스트의 끝 부분 


{4}

문자 리스트를 정확하게 4 회 반복 적용


|

대체(alternation) 메타문자 - 첫 번째 선택을 종료하고 두 번째 대체 표현식을 시작


[

문자 리스트의 시작 


[:digit:]

POSIX numeric digit 클래스. 


]

문자 리스트의 끝 부분 


{9}

문자 리스트를 정확하게 9 회 반복


)

대체를 위해 사용된 서브표현식 그룹을 종료하는 괄호 기호


$

라인의 끝부분을 의미하는 앵커 메타문자 (매치된 패턴 이후에 어떤 문자도 뒤따라 올 수 없음)


 


([-_,:;'"\/\[\]\(\)\.]|[^a-zA-Z0-9])ae([-_,:;'"\/\[\]\(\)\.]|[^a-zA-Z0-9])


출처 : http://zoot235.egloos.com/10088226

'IT > JAVA' 카테고리의 다른 글

정규표현식(regexp)  (0) 2017.05.24
JAVA 정규표현식  (0) 2017.05.19
Posted by 경제/부동산/프로그래머/안드로이드/PHP/mysql/asp 당양부부

2017.05.19 17:26 IT/JAVA

JAVA 정규표현식

JAVA 정규표현식


1) ‘.’ 특수문자

- 임의의 한 문자를 나타낸다.

- ‘.’ 특수문자가 위치한 곳에는 반드시 한 글자가 위치하여야 한다.

- ex ) 패턴 : a.b → 일치하는 문자열 : acb, adb, azb 등

- ex ) 패턴 : ab. → 일치하지 않는 경우 : ab, abcd 등

 

2) ‘*’ 특수문자

- 바로 앞의 문자를 0번 이상 반복한다.

- * 앞에는 한 글자 이상의 단어가 반드시 와야 한다.

- ex ) 패턴 : ab*c → abc, abbc, abbbc 등

- ex ) 패턴 : *ab → 불가능

 

3) ‘+’ 특수문자

- 바로 앞의 문자를 1번 이상 반복한다.

- + 앞에는 한 글자 이상의 단어가 반드시 와야 한다.

- ex ) 패턴 : a+b → aab, aaab, aaaab 등

- ex ) 패턴 : +ab → 불가능

 

4) ‘?’ 특수문자

- 특수문자 바로 앞의 문자가 하나 있거나 없는 것을 의미한다.

- ex ) 패턴 : try? → 일치하는 문자열 : tr, try

패턴 : a?c → 일치하는 문자열 : c, ac

 

5) ‘^’ 특수문자

- 문장의 처음을 나타낸다.

- ex ) 패턴 : ^Hello → 일치하는 문자열 : Hello abc, Hello world 등

Hello로 시작하는 문자열

 

6) ‘$’ 특수문자

- 문장의 끝을 나타낸다.

- ex ) 패턴 : world$ → 일치하는 문자열 : hello world, welcome my world 등

world로 끝나는 문자열

 

7) ‘[]’ 특수문자

- 괄호 안의 문자 중 일치하는 것을 찾고자 할 경우 사용

- ex ) 패턴 : [abc] → 일치하는 문자열 : a, b, c, ab, abc 등

[a-z] → 소문자가 포함된 모든 문자열

[A-Z] → 대문자가 포함된 모든 문자열

[0-9] → 숫자가 포함된 모든 문자열

^[a-zA-Z0-9] → 숫자가 영문자로 시작되는 모든 문자열

 

8) ‘[]’ 특수문자 안에서의 ‘^’ 특수문자

- []안의 문자와 일치하지 않는 문자열을 포함하고 있는 패턴을 의미한다

- ex ) 패턴 : [^abc]de → .de패턴과 동일 (ade, bde, cde 제외)

 

9) ‘{}’ 특수문자

- 특수문자 앞의 문자나 문자열의 반복되는 개수를 말한다.

- ex ) go{5}ggle → gooooogle

go{3,}ggle → gooogle, goooogle, gooooogle 등 (o가 3개 이상)

go{2,4}ggle → google, gooogle, goooogle (o가 2개이상 4개이하)

 

10) ‘()’ 특수문자

- ()안의 글자들을 하나의 문자로 본다.

- ex ) (hero_){3} → hero_hero_hero_

(hero_)* → null, hero_, hero_hero_ 등

 

11) ‘|’ 특수문자

- 패턴 안에서 OR연산 사용시 사용

- ex ) man|woman → man, woman, manwoman, superman 등

 

12) 문자 클래스

- [] 안에서 자주 사용되는 패턴들을 미리 키워드로 정의하여 놓은 것

- 문자클래스는 PHP에서는 이용되지만 JAVA에서는 이용되지 않음

패턴

문자 클래스

J2SDK 1.4의 예

[a-zA-Z] : 모든 영문자

[[:alpha:]]

\p{Alpha}

[0-9] : 숫자

[[:digit:]]

\p{Digit}

[a-zA-Z0-9] : 영문자와 숫자

[[:alnum:]]

\p{Alnum}

공백

[[:space:]]

\p{Space}



 

javascript 에서 사용 !!!


 

# 매칭문자

\D : 숫자가 아닌 문자

\d : 숫자

\s : 공백문자

\w : [A-Z,a-z,0-9], 알파벳, 숫자로 된 문자, 밑줄기호

\W : \w를 제외한것

 

flag - i : 대/소문자 구분 없음

        g : 전역검색

        m : 여러줄 검색

 

정규식 매칭중 () 사용시 괄호로 묶은 패턴은 매칭후 그 부분을 기억하여 결과가 저장되는 배열에 같이 저장된다.

괄호로 묶은 부분만 저장된다.

 

ex1 ) var rgExp = /(^D*[0-9])/

        var str = "This is fun 01 stuff";

        var resultArray = str.match(rgExp);

        document.writeln(resultArray);        ==>  This is fun 0,This is fun 0

       

ex2 ) var rgExp = /(^D*)[0-9]/

        var str = "This is fun 01 stuff";

        var resultArray = str.match(rgExp);

        document.writeln(resultArray);        ==>  This is fun 0,This is fun

 

ex3 ) 숫자에 Comma 추가하기 (출처 : 바로가기 >> )

        function addComma(num) {

                  if(isNaN(num) == true) {

                        return 0;

                  }

                  var reg = /(^[+-]?\d+)(\d{3})/;

                  var strNum = num + '';

                  while(reg.test(strNum)) {

                        strNum = strNum.replace(reg, '$1' + ',' + '$2');

                  }

                  return strNum

           }

        ==> "123456789" -> (123456789 replace) -> "123456,789" -> (123456 replace) -> "123,456,789"

 

감사합니다.


출처: http://breath91.tistory.com/entry/Java-정규표현식 [숨[Breath]]

'IT > JAVA' 카테고리의 다른 글

정규표현식(regexp)  (0) 2017.05.24
JAVA 정규표현식  (0) 2017.05.19
Posted by 경제/부동산/프로그래머/안드로이드/PHP/mysql/asp 당양부부
이전버튼 1 이전버튼

블로그 이미지
경제를 좋아하는 일산의 행복한 프로그래머입니다. 감사합니다.
당양부부
Yesterday67
Today3
Total110,534

달력

 « |  » 2018.08
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

최근에 달린 댓글

최근에 받은 트랙백

글 보관함