Tag Archives: 정규식

그루비(Groovy) 튜토리얼 5 – 정규식 결과 집합 만들기 (Capturing regex groups)

그루비(Groovy) 튜토리얼 5 - 정규식 결과 집합 만들기 (Capturing regex groups)
2008.4.10 translation & editing by gilbird
원문: wiki-snapshot.pdf  pp. 263-266

Naver 태그: 그루비,groovy,자바,java,tutorial

검색결과 집합 (Capture Groups)

그루비에서 가장 유용한 특징 중의 하나로 정규식으로 데이터에서 정규식 검색 결과 집합을 구성하는 기능이 있다. 예를 들어 다음과 같이  England의 Liverpool의 위치 데이터를 추출한다고 해보자.

locationData = “Liverpool, England: 53° 25? 0? N 3° 0? 0?”

데이터 추출을 위하여 string의 split()함수를 써서 Liverpool과 England 사이의 쉼표, 기타 특수문자를  제거한다. 아니면 정규식 한 줄로 해결할 수도 있는데 식을 만들고 나면 다소 복잡해 보일 수도 있다.  우선 관심있는 것들을 모두 괄호로 묶어 놓는다.

myRegularExpression = /([a-zA-Z]+), ([a-zA-Z]+): ([0-9]+). ([0-9]+). ([0-9]+). ([A-Z])([0-9]+). ([0-9]+). ([0-9]+)./
다음은 ~= 연산자로 “matcher”를 정의한다.
matcher = ( locationData =~ myRegularExpression )

matcher변수는 그루비에서 향상시킨 java.util.regex.Matcher를 내장하고 있다. 데이터는 Matcher 객체로부터 자바에 있는 것처럼 액세스할 수 있다. 그루비 개발자가 데이터를 가져오는 방법은 matcher를 써서 2차원 배열인 것처럼 사용하는 것이다. 2차원 배열은 배열의 배열이다. 위의 경우에 배열의 첫번째는 문자열이 정규식에 각각 일치한 값들이다. 이 예에서 정규식은 한번만 일치하며 2차원 배열의 첫번째 엘리먼트는 한개 뿐이다. 다음 코드를 보자.

matcher[0]

위 식의 결과는 아래와 같이 나와야 한다.

[“Liverpool, England: 53° 25? 0? N 3° 0? 0?”, “Liverpool”, “England”, “53”, “25”, “0”, “N”,“3”, “0”, “0”]

그리고 배열의 두번째 차원을 액세스해서 찾아보고자하는 검색 결과 집합(capture group)을 액세스 할 수 있다.

if (matcher.matches()) {    println(matcher.getCount()+ ” occurrence of the regular expression was found in the string.”);    println(matcher[0][1] + ” is in the “ + matcher[0][6] + ” hemisphere. (According to: “         + matcher[0][0] + “)”)}

정규식을 이용하여 얻을 수 있는 이점은 데이터가 규칙적(well-formed)인지 볼 수 있다는 것이다. 즉  locationData가 “Could not find location data for Lima, Peru”라면 if문 안을 실행하지 않을 것이다.

검색결과외 집합 (Non-matching Groups)

검색 결과 이외의 집합을 만드는 식을 사용하는 것이 좋을 수도 있는데 괄호안의 맨앞에 ?: 두 글자를 넣으면 된다. 예를 들어 몇몇 사람의 중간 이름이 무것이든지 없애고 맨앞과 맨뒤 글자를 뒤바꿔 출력 하고자 한다면 아래와 같이 한다.

names = [    “Graham James Edward Miller”,    “Andrew Gregory Macintyre”]printClosure = {    matcher = (it =~ /(.*?)(?: .+)+ (.*)/); // 중간에 검색결과외 집합이 있다.    if (matcher.matches())        println(matcher[0][2]+“, “+matcher[0][1]);}names.each(printClosure);

위의 결과는 아래와 같다.

Miller, GrahamMacintyre, Andrew

위와 같이 하면 성이 두번째 일치 집합에 들어 있음을 알 수 있다.

치환 (Replacement)

정규식으로 할 수 있는 가장 간단하고 유용한 작업은 문자열의 일부를 치환하는 것인데 java.util.regex.Matcher (이 객체는 myMatcher = (“a” += /b/)와 같은 식을 사용하면 나온다)의 replaceFirst()와 replaceAll() 함수를 쓰면 된다.

Harry Potter 이름을 전부  Tanya Grotter로 치환해서 J.K Rewlings의 책을 재판매하고 싶다고 해보자 (누군가 이런 짓을 했다. 궁금하면 검색해보라).

excerpt = “At school, Harry had no one. Everybody knew that Dudley’s gang hated that odd Harry Potter “+    “in his baggy old clothes and broken glasses, and nobody liked to disagree with Dudley’s gang.”;matcher = (excerpt =~ /Harry Potter/);excerpt = matcher.replaceAll(“Tanya Grotter”);matcher = (excerpt =~ /Harry/);excerpt = matcher.replaceAll(“Tanya”);println(“Publish it! “+excerpt);

이 경우 Harry Potter의 이름, 성+이름 두 가지에 대해서 치환이 된다.

최소동작 연산자 (Reluctant Operators)

?, +, *는 게걸스러운 연산자라서 가능한 많은 입력을 일치 시키려고 한다. 때로는 이 방법이 원하지 않는 것일 수도 있다. 아래는 15세기 교황 리스트를 가지고 이야기 해보자.

popesArray = [    “Pope Anastasius I 399-401”,    “Pope Innocent I 401-417”,    “Pope Zosimus 417-418”,    “Pope Boniface I 418-422”,    “Pope Celestine I 422-432”,    “Pope Sixtus III 432-440”,    “Pope Leo I the Great 440-461”,    “Pope Hilarius 461-468”,    “Pope Simplicius 468-483”,    “Pope Felix III 483-492”,    “Pope Gelasius I 492-496”,    “Pope Anastasius II 496-498”,    “Pope Symmachus 498-514”]

위 예에서 (일련번호나 수식어구 없는) 이름만을 파싱해 내는 정규식을 만들어 보자.

/Pope (.*)(?: .*)? ([0-9]+)-([0-9]+)/

위 식은 아래와 같이 나누어 볼 수 있다.

/Pope(.*)(?: .*)?([0-9]+)([0-9]+)/
정규식 시작Pope0개 이상의 글자검색결과외 집합: 공백문자와 0개 이상의 글자숫자숫자정규식 끝

위의 모든 예에서 첫번째 일치 집합은 교황의 이름만이 나올 것으로 기대 했으나 실제로 나온 결과는 수식어 까지 인식이 되버린다. 예를 들어 첫번째 교황은 다음과 같이 쪼개진다.

/Pope(.*)(?: .*)?([0-9]+)([0-9]+)/
정규식 시작PopeAnstasius I 399401정규식 끝

위 사실로 보아 첫번째 결과 집합에서 너무 많은 인식을 하고 있다. 첫번째 결과 집합에서는 Anatasius 만 가져오고 수식어구는 두번째 결과 집합에 들어가길 원했다. 방법을 바꾸어 첫번째 결과 집합에 최소한의 입력만 인식하도록 해보자. 이 경우는 공백 전까지의 모든 것이 해당된다. 자바 정규식에서는 *, +, ? 연산자의 최소 동작(reluctant) 버전을 지원한다. *+? 세가지 연산자 중 하나를 최소로 동작하게 하려면 간단하게 연산자 다음에 ?를 넣으면 된다(*?, +?, ??). 그래서 새로운 정규식은 아래와 같다.

/Pope (.*?)(?: .*)? ([0-9]+)-([0-9]+)/

이제 새로운 정규식으로 난이도 높은 입력의 하나로 Pope Hilarius를 처리해 보도록 하자. 결과는 아래와 같다.

/Pope(.*)(?: .*)?([0-9]+)([0-9]+)/
정규식 시작PopeLeoI the Great440461정규식 끝

이 결과가 바로 우리가 원하는 것이다.


테스트를 위하여 다음 코드를 실행해 보기 바란다.

popesArray = [    “Pope Anastasius I 399-401”,    “Pope Innocent I 401-417”,    “Pope Zosimus 417-418”,    “Pope Boniface I 418-422”,    “Pope Celestine I 422-432”,    “Pope Sixtus III 432-440”,    “Pope Leo I the Great 440-461”,    “Pope Hilarius 461-468”,    “Pope Simplicius 468-483”,    “Pope Felix III 483-492”,    “Pope Gelasius I 492-496”,    “Pope Anastasius II 496-498”,    “Pope Symmachus 498-514”]myClosure = {    myMatcher = (it =~ /Pope (.*?)(?: .*)? ([0-9]+)-([0-9]+)/);    if (myMatcher.matches())        println(myMatcher[0][1]+“: “+myMatcher[0][2]+” to “+myMatcher[0][3]);}popesArray.each(myClosure);
 
위 코드의 결과 비교차원에서 처음 제시한 정규식도 넣어서 실행해 보기 바란다. 

그루비(Groovy) 튜토리얼 4 – 정규식(Regular Expression) 기본

그루비(Groovy) 튜토리얼 4 - 정규식(Regular Expression) 기본

2008.3.25 translation & editing by gilbird

원문: http://groovy.codehaus.org/Tutorial+4+-+Regular+expressions+basics

정규식(Regular Expression)

정규식은 텍스트 처리의 스위스 아미 나이프라고 할 수 있다. 정규식으로 문자열의 패턴을 찾아 추출할 수 있다. 가장 간단한 정규식의 예로는 문자와 숫자가 있다. 그리고 가장 간단한 식으로는 ==~를 사용한 정규식이 있다. 예를 들어 ‘potatoe’와 문자열이 일치하는지 보려면 다음과 같이 한다.

“potatoe” ==~ /potatoe/

groovyConsole에 위 식을 입력하여 실행하면 true를 리턴할 것이다. 몇가지 주목할 만한 점이 있다. 첫번째는 ==와 유사한 ==~ 연산자인데 정확히 일치하는 패턴에 대해서만 일치한다. 두번째는 정규식이 /로 둘러쌓아서 그루비에게 일반 문자열이 아닌 정규식임을 알린다.

정확한 철자가 일치하는지 체크하길 원하는데 ‘e’ 다음에 ‘?’를 추가하면 e는 선택사항(있어도 되고 없어도 됨)이다. 다음 정규식은 true다.

“potatoe” ==~ /potatoe?/

정확한 철자도 일치한다.

“potato” ==~ /potatoe?/

다음은 앞의 두경우 모두 해당되지 않으며 일치하지 않는다.

“motato” ==~ /potatoe?/

다음은 정규식을 가진 간단한 대수식(boolean expression)을 정의하는 방법이다. 정규식을 테스트하는 메서드를 만들어보자. 예를 들어 Pete Winsniewski의 성과의 일치여부를 체크하는 코드를 만들어 보자.

def checkSpelling(spellingAttempt, spellingRegularExpression) {        if (spellingAttempt ==~ spellingRegularExpression) {               println(“Congratulations, you spelled it correctly.”)         } else {               println(“Sorry, try again.”)        }}theRegularExpression = /Wisniewski/checkSpelling(“Wisniewski”, theRegularExpression)checkSpelling(“Wisnewski”, theRegularExpression)

위 코드에서는 몇가지 특이한 점이 있다. 첫번째로 함수를 정의하였다(실제로는 메서드지만 두 단어를 혼용해서 쓰겠다). 함수는 클로저와 유사한 코드의 집합이다. 클로저는 익명일 수 있지만 함수는 항상 이름을 가지고 있다. 한번 정의하면 나중에 계속 쓸 수 있다.

checkSpelling 함수에서 if문은 주어진 파라메터 spellingAttempt와 spellingRegularExpression의 패턴이 일치하는지 ==~ 연산자로 검사한다.

checkSpelling 함수를 이용하여 이름의 중앙에 ‘w’를 가지지 않은 문자열을 찾고 싶은 경우 다음과 같이 할 수 있다:

theRegularExpression = /Wisniew?ski/checkSpelling(“Wisniewski”, theRegularExpression)checkSpelling(“Wisnieski”, theRegularExpression)checkSpelling(“Wisniewewski”, theRegularExpression)

checkSpelling함수의 spellingRegularExpression 인자로 들어간 theRegularExpression값에 ? 한개는 바로 앞의 문자(‘w’)는 선택사항이라는 것이다. 이 코드를 spellingAttempt에 다른 w의 위치에 다른 철자를 넣어 두 가지 철자법 ‘Wisniewski’와 ‘Wisnieski’만 일치함을 증명해보자.

?는 정규식에서 특별한 의미임을 기억하기 바란다.

단어 중앙의 “ie” 순서가 바뀌어도 일치한 것으로 보이도록 해보자.

theRegularExpression = /Wisn(ie|ei)w?ski/checkSpelling(“Wisniewski”, theRegularExpression)checkSpelling(“Wisnieski”, theRegularExpression)checkSpelling(“Wisniewewski”, theRegularExpression)

위의 정규식으로 철자에 대해서 이야기 해보자. ‘Wisniewski”, “Wisneiwski”, “Wisnieski”, Wisneiski” 4가지 철자가 일치하는 것으로 나온다. 막대 문자 ‘|’는 왼쪽이나 오른쪽 항목(위의 경우에는 “ie”나 “ei”)이 수락 가능한 것임을 말한다.  괄호는 간단하게 관심 부분의 시작과 끝임을 표시한다.

정규식 중 흥미로운 특징중의 하나로 문자집합을 지정하여 일치를 허용하는 방법이 있는데 꺽쇄괄호[]를 사용한다.

다음과 같이 Pete의 성에 다양한 철자법 오류를 시도해 보자.

theRegularExpression = /Wis[abcd]?niewski/ // ‘a’, ‘b’, ‘c’ , ‘d’ 중의 하나 혹은 없음
theRegularExpression = /Wis[a-zA-Z]niewski/ // 소문자나 대문자가 필요함
theRegularExpression = /Wis[^abcd]niewski/ // ‘a’, ‘b’, ‘c’ , ‘d’ 가 아닌 문자가 필요함

마지막 문장의 [] 처음에 있는 ^는 꺽쇄괄호 안에 지정한 문자를 제외한 나머지 문자를 말한다.   

연산자

이제 정규식의 동작 방식을 이해했을 것이다. 다음은 유용한 연산자들에 대한 내용이다.

정규식 연산자

a? a가 0개 혹은 1개 발생하면 일치 ‘a’ 나 빈 문자열
a* a가 0 혹은 그 이상 발생할 때 일치 빈 문자열이나 ‘a’, ‘aa’, ‘aaa’, 등
a+ a가 1번 이상 발생하면 일치‘a’, ‘aa’, ‘aaa’, 등
a|b a 나 b면 일치‘a’ 나 ‘b’
. 한개의 문자면 일치 ‘a’, ‘q’, ‘l’, ‘_’, ‘+’, 등
[woeirjsd] 지정한 문자들 중 하나 이면 일치 ‘w’, ‘o’, ‘e’, ‘i’, ‘r’, ‘j’, ‘s’, ‘d’
[1-9] 범위 안의 문자면 일치 ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’
[^13579] 지정한 문자 이외의 문자이면 일치 짝수 혹은 문자
(ie) 수식을 묶음 (다른 연산자와 사용하기 위함) ‘ie’
^a 줄의 맨 처음에 a가 있으면 일치‘a’
a$ 줄의 맨 끝에 a가 있으면 일치 ‘a’

 

?와 같이 위에 나와 있는 연산자를 실제 문자로 사용하려면 문자 앞에 ‘\’를 넣으면 된다.

// ?가 제일 끝에만 나오는 문장은 true
“How tall is Angelina Jolie?” ==~ /[^\?]+\?/

위 예는 가독성이 떨어진다. (PERL에서는 이렇게 많이 사용하는데 “write only” 언어로 여겨지는 이유 중의 하나이다.) 

정규식 (Regular Expression) 특수문자 처리

(1) ^ (caret)
라인의 처음이나 문자열의 처음을 표시

예 : ^aa (문자열의 처음에 aa를 포함하면 참, 그렇지 않으면 거짓)

(2) $ (dollar)
라인의 끝이나 문자열의 끝을 표시

예 : aaa$ (문자열의 끝에 aaa를 포함하면 참, 그렇지 않으면 거짓)

(3) . (period)
임의의 한 문자를 표시

예 : ^a.c (문자열의 처음에 abc, adc, aZc 등은 참, aa 는 거짓)
예 : a..b$ (문자열의 끝에 aaab, abbb, azzb 등을 포함하면 참)

(4) [] (bracket)
문자의 집합이나 범위를 나타냄, 두 문자 사이의 범위는 “-” 사용.
[]내에서 “^”이 선행되면 not을 나타냄

예 : [abc] (a, b, c 중 어떤 문자, “[a-c].”과 동일)
예 : [Yy] (Y 또는 y)
예 : [A-Za-z0-9] (모든 알파벳과 숫자)
예 : [-A-Z]. (“-“(hyphen)과 모든 대문자)
예 : [^a-z] (소문자 이외의 문자)
예 : [^0-9] (숫자 이외의 문자)

(5) {} (brace)
{} 내의 숫자는 직전의 선행문자가 나타나는 횟수,범위를 나타냄

예 : a{3} (‘a’의 3번 반복인 aaa만 해당됨)
예 : a{3,} (‘a’가 3번 이상 반복인 aaa, aaaa,  … 등을 나타냄)
예 : a{3,5} (aaa, aaaa, aaaaa 만 해당됨)
예 : ab{2,3} (abb와 abbb 만 해당됨)
예 : [0-9]{2} (두 자리 숫자)
예 : doc[7-9]{2} (doc77, doc87, doc97 등이 해당)
예 : [^Zz]{3} (Z와 z를 포함하지 않는 5개의 문자열, abc, ttt 등)
예 : .{3,4}er (‘er’앞에 세 개 또는 네 개의 문자를 포함하는 문자열이므로 Peter, mother 등이 해당)

(6) * (asterisk)
“*” 직전의 선행문자가 0번 또는 여러번 나타나는 문자열

예 : ab*c (‘b’를 0번 또는 여러번 포함하므로 ac, abc, abbbc 등)
예 : * (선행문자가 없는 경우이므로 임의의 문자열 및 공백 문자열)
예 : .* (선행문자가 “.”이므로 하나이상의 문자를 포함하는 문자열)
예 : ab* (‘b’를 0번 또는 여러번 포함하므로 a, accc, abb 등)
예 : a* (‘a’를 0번 또는 여러번 포함하므로 k, kd, a, aa, abb 등)
예 : doc[7-9]* (doc7, doc777, doc778989, doc 등이 해당)
예 : [A-Z].* (대문자로만 이루어진 문자열)
예 : like.* (직전의 선행문자가 ‘.’이므로 like에 0 또는 하나 이상의 문자가 추가된 문자열이 됨, like, likely, liker, likelihood 등)

(7) + (Plus Sign)
“+” 직전의 선행문자가 1번 이상 나타나는 문자열

예 : ab+c (‘b’를 1번 또는 여러번 포함하므로 abc, abcd, abbc 등)
예 : ab+ (‘b’를 1번 또는 여러번 포함하므로 ab, abcc, abb 등)
예 : [A-Z]+ (대문자로만 이루어진 문자열)
예 : like.+ (직전의 선행문자가 ‘.’이므로 like에 하나 이상의 문자가 추가된 문자열이 됨, likely, liker, likelihood 등, 그러나 like는 해당안됨)

(8) ? (question mark)
“?” 직전의 선행문자가 0번 또는 1번 나타나는 문자열

예 : ab?c (‘b’를 0번 또는 1번 포함하므로 abc, abcd 만 해당됨)

(9) () (parenthesis)
()는 정규식내에서 패턴을 그룹화 할 때 사용

(10) | (bar)
or를 나타냄

예 : a|b|c (a, b, c 중 하나, 즉 [a-c]와 동일함)
예 : yes|Yes (yes나 Yes 중 하나, [yY]es와 동일함)
예 : korea|japan|chinese (korea, japan, chinese 중 하나)

(11) \ (backslash)
위에서 사용된 특수 문자들을 정규식내에서 문자로 취급하고 싶을 때 ‘\’를 선행시켜서 사용하면됨

예 : filename\.ext (“filename.ext”를 나타냄)
예 : [\?\[\\\]] (‘?’, ‘[‘, ‘\’, ‘]’ 중 하나)

정규식(Regular Expression) 표현 방법 및 예제

1) 객체

그럼 먼저 정규식의 객체에 대해 살펴보자. 정규식의 모든 객체를 설명하려면 너무 복잡하고 어려우므로 여기에선 일단 가장 중요한 것들만 나열한다.

(1) 문자

    * 유니코드 문자 – 유니코드 문자는 문자 그대로 표현한다. 즉, a는 문자열의 a와 매치된다.
    * (backslash) – 정규식에 사용되는 특수문자, 예를 들어 * 나 등을 매치할때 사용한다. 즉, * 를 매치하려면 * 라고 써줘야한다.
    * – 탭 문자와 매치된다.
    *
– 새줄문자와 매치된다.
    *
– 리턴문자와 매치된다.
    * f – form feed문자와 매치된다.

예를 들어 문자열 “ac*”와 매칭을 하고 싶다면 정규식은 “ac*”와 같이 사용한다. 와 *가 모두 정규식에 쓰이는 특수문자들이므로 앞에 을 붙여주고 나머지는 문자 그대로 사용한다.

(2) 문자클래스

    * [a-zA-Z] – a에서 z까지, 그리고 A에서 Z사이에 있는 모든 문자와 매치된다.
    * [^a-zA-Z] – 위와 반대다. 즉 a에서 z까지, A에서 Z까지 사이에 없으면 매치된다.

만약 소문자와 매치하려면 [a-z]를 사용하거나 [^A-Z]를 사용하면 된다. 숫자도 마찬가지다. [0-9]를 사용하면 숫자와 매치되고 숫자가 아닌 것과 매치하려면 [^0-9]를 사용하면 된다.

(3) 사전에 정의된 클래스

    * . – 새줄문자 이외의 모든것
    * w – 알파벳과 _ (영어단어에 쓰이는 문자)
    * W – 알파벳과 _이 아닌 것
    * s – 빈 공간
    * S – 빈 공간이 아닌 것
    * d – 숫자
    * D – 숫자가 아닌 것

예를 들어 “1a 2a” 또는 “3g 9i” 등의 문자열과 매치하고 싶을 땐 “dSsdS”와 같이 정규식을 써주면 된다.

(4) 단어나 줄의 경계를 매치할때

    * ^ – 줄의 맨앞과 매치된다.
    * $ – 줄의 맨끝과 매치된다.
    *  – 단어와 단어의 경계와 매치된다.

예를 들어 한 줄에 “aaaaa”라는 문자열만 있는 줄을 매치하고 싶으면 “^aaaaa$”와 같이 정규식을 써주면 된다. 만약 다른 문자열 속에 포함돼있는 “aaaaa”를 매치하고 싶다면 (예를 들어 “bbbbbaaaaabbbbb”) 그냥 “aaaaa”만 해줘야 매치가 된다.

(5) 그 이외의 것들

    * A|B – A 또는 B와 매치된다.
    * (A) – A와 매치한것을 나중에 다시 사용할 때 쓴다.

어떤 문자열에서 매치한 부분을 나중에 다시 사용하고 싶을 때는 괄호를 사용한다. 예를 들어 사용자가 입력한 전화번호를 정규식을 사용하여 패턴매칭을 했다고 하자. 이렇게 매치된 전화번호를 데이터베이스에 저장하고 싶을 때 바로 정규식 안에서 괄호를 이용하여 매칭을 한다. 괄호 안에 매칭된 부분은 나중에 다시 사용하는 것이 가능하기 때문이다. 이것은 굉장히 중요하므로 나중에 예제로 다시 설명하겠다.

(6) 매치된 객체의 재사용

    *  1 – 첫번째 괄호에 매치된 부분
    *  2 – 두번째 괄호에 매치된 부분
    *  세번째는 $3, 네번째는 $4 등으로 사용하면 됨

정규식 안에서 괄호에 매치된 부분을 다시 사용하고 싶을 때 쓰는 객체들이다. 예를 들어 “1 – 1” 처럼 처음과 나중의 숫자가 같은 문자열만 매칭하고 싶을 경우, “(d+) – 1″과 같은 정규식을 사용하면 간단하게 매칭할 수 있다. 여기서 1 은 그 앞에서 d+ 로 매치된 숫자를 가리킨다.

(7) 수량

수량은 각 객체가 문자열 안에서 몇 번이나 나타나는지 그 회수를 정해준다. 아마 많은 독자들이 윗부분을 보면서 정규식은 문자를 한 번에 한 개밖에 매치하지 못하나 하고 의문을 품을지 모르겠다. 그러나, 바로 밑에 나열한 것들로 수량을 정해줄 수 있다. 일단 그것들을 보고 예제를 통해서 사용 방법을 살펴보자.

    * A* – A를 0번, 아니면 그 이상 매치한다.
    * A+ – A를 한번, 아니면 그 이상 매치한다.
    * A? – A를 0번, 아니면 한번만 매치한다.
    * A{n} – A를 정확히 n번 매치한다.
    * A{n,} – A를 n번 이상 매치한다.
    * A{n,m} – A를 최소한 n번, 하지만 m번 이하로 매치한다.

2) 정규식 예제

지금까지 나열한 모든 객체들을 예제를 통해서 자세히 알아보도록 하자. 만약 전화번호를 매치하고 싶다면 어떻게 해야할까? 일단 전화번호는 지역번호가 있을수도, 없을수도 있다. 사람마다 지역번호를 괄호에 넣거나, 아니면 그냥 국번과 -로 구별하기도 한다. 그럼 그것에 맞는 정규식은 어떻게 써야할까? 일단 지역번호를 매치해보자. 지역번호는 세자리 숫자이므로

d{3}

으로 하면 매치가 된다. 물론 너무 엄격하게 하고 싶지 않으면

d+

로 해도 된다. 그렇다면 괄호의 있고 없고 여부는 어떻게 해야할까? 여기에선 ?나 *를 쓰면 해결할 수 있다. 즉,

(?d{3})?

을 쓰면 지역번호와 패턴매칭을 할 수 있다. 전화번호의 나머지도 간단하다.

d{3,4}-?d{4}

로 하면 간단히 매치된다. 국번은 세자리, 또는 네자리지만 번호는 네자리밖에 없다. 요약하면 전화번호를 매치하기 위해선

(?d{3})?-?d{3,4}-?d{4}

와 같은 정규식이 필요하다. 그럼 위의 정규식을 써서 전화번호를 찾아냈다고 하자. 하지만 그 전화번호가 무엇인지 어떻게 알 수 있을까? 문자열을 그대로 다시 출력하면 매칭한 부분뿐만 아니라 다른 부분들까지 출력하게 된다. 여기서 매치된 부분만 다시 사용하기 위해 괄호를 사용하면 된다. 예를 들어, 위의 전화번호를 지역번호와 국번, 그리고 번호의 세 부분으로 나눠서 재사용 해보기로 하자. 그렇다면 다음처럼 각 부분에 괄호를 사용하면 된다.

(?(d{3}))?-?(d{3,4})-?(d{4})

처음보단 훨씬 복잡하게 보이지만 객체 하나하나를 풀어서 보면 쉽게 알 수 있다. 만약 전화번호가 123-456-7890 이였다면 첫번째 괄호는 123, 두번째 괄호는 456, 그리고 마지막 괄호는 7890과 매치하게 된다. 이제 매치된 부분을 재사용하려면 Regexp 패키지의 getParen()이라는 함수를 사용하면 된다. 즉, getParen(1)은 123을, getParen(2)는 456을, 그리고 getParen(3)은 7890을 돌려준다. 이것은 클래스 사용방법에 더 자세히 설명돼 있으므로 패키지 사용방법 문서를 읽어주기 바란다.

그럼 여기서 연습을 한 번 해보자. 만약 주민등록번호를 매치하고 싶다면 어떤 정규식을 써야할까? 이건 독자 여러분이 각자 해보기 바란다. 정답은 이 문서 맨 밑에 있다.

여기서 한 가지 짚고 넘어가야 할 것은 정규식엔 한 가지의 정답이란 없다는 것이다. 개발자가 원하는 결과가 제대로 나오도록만 정의해주면 된다는 것이다. 예를 들어 앞의 전화번호의 예제를 보자. 국번의 경우 d{3} 도 가능했고 d+ 도 가능했다. 개발자가 원하는 것을 사용하면 된다.

RegExp 사용법

1. RegExp 객채를 생성한다.
  var regexp = CreateRegExp(“Text To Find”,”i”);// i를 빼면 대소문자를 구분한다.

2. Replace 한다.
  Result_Text = regexp.Replace(source_text, “바꾼자리에 채울 문자열”);예제.

다음 문장에서 hate라는 단어를 love로 치환하려면….

var find_txt = “hate”;
var replace_txt = “love;
var regexp = CreateRegExp(find_txt,”i”);
var src_txt = “I hate you.”;
var result_txt = regexp.Replace(src_txt,replace_txt);
alert(result_txt);

정규식으로 문자열 바꿔주기

php에 ereg_replace라는 함수가 있다.

이를 이용하면 정규식을 이용하여 문자열을 바꿀 수 있다.


문법

문자열 = ereg_replace( “정규식”, “바꾸고자 하는 문자열”, “원본 문자열”);


// 예제 1 – 비정규식 사용
$src=”i have have have five five egg”;
echo ereg_replace(“have”, “”, $src) . “<br>”;


// 예제 2 – 비정규식 사용
$src=”<div style=blahblah> hello world”;

echo ereg_replace(“<div(.*?)>”, “”, $src) . “<br>”;