정규표현식 의 핵심. 패턴변경자 1

대단할것은 없는 강좌이지만,
제 강좌를 출처를 밝히고 외부로 퍼가는 것은 허용하지만,
다른 강좌의 자료나 책의 자료로 사용되거나 부분적인 인용은 허용하지 않습니다.

강좌는 php 5. 대를 기준으로 하며, PCRE (펄과 호환 되는 정규표현식)을 다룹니다.
PCRE 는 preg_ 로 시작되는 내장함수와 함께 사용되어지는 정규표현식을 말합니다.

PCRE > 정규표현식 의 핵심. 패턴변경자 1

이전 내용에서는 정규표현식의 메타문자에 대해서 알아보았습니다.
이번 내용에서도 역시 정규표현식의 핵심이라고 볼수 있는 패턴변경자에 대해서 이어서 알아보도록 하겠습니다.

패턴변경자란?
쉽게 설명하자면, 복잡해질수 있는 패턴을 쉽게 표현 가능하도록 해주는 것입니다.

1. i
이것은 주어진 패턴으로 문자열을 검사하되 대소문자는 구별하지 않겠다 는 것입니다.

즉, /^[a-z]+$/ 이렇게 사용한다면, 알파벳 소문자로만 이루어진 문자열을 찾는것이고
/^[a-z]+$/i 와 같이 사용한다면, /^[a-zA-Z]+$/ 와 같은 방법인 대소문자 구분없이 알파벳으로 이루어진 문자열을 찾는것입니다.

예제18> test18.php

<?php

$string = "zOOzoOZOozooZooZOO";

$patterns = Array();
$patterns[] = "/[a-z]{3}/"// 연속된 알파벳 소문자 세자를 찾는 패턴
$patterns[] = "/[A-Z]{3}/"// 연속된 알파벳 대문자 세자를 찾는 패턴
$patterns[] = "/[a-zA-Z]{3}/"//대소문자 구분없이 연속된 알파벳 대문자 세자를 찾는 패턴
$patterns[] = "/[a-z]{3}/i"// i 패턴 변경자를 사용하여 대소문자 구분없이 연속된 알파벳 세자를 찾는 패턴
$patterns[] = "/[A-Z]{3}/i"// i 패턴 변경자를 사용하여 대소문자 구분없이 연속된 알파벳 세자를 찾는 패턴

$patterns[] = "/zoo/"// zoo 를 찾는 패턴
$patterns[] = "/ZOO/"// ZOO 를 찾는 패턴
$patterns[] = "/[zZ][oO][oO]/"//대소문자 구분없이 zoo 를 찾는 패턴
$patterns[] = "/zoo/i"// i 패턴 변경자를 사용하여 대소문자 구분없이 zoo 를 찾는 패턴
$patterns[] = "/ZOO/i" // i 패턴 변경자를 사용하여 대소문자 구분없이 zoo 를 찾는 패턴

foreach($patterns as $pattern){

    if (preg_match($pattern, $string, $m)) {

        echo '<font color="blue">' . htmlspecialchars($pattern) . ' ==> ' . $string . " 은 패턴에 매치되는 문자열을 포함한 문자열 입니다. <br>" . $m[0] . "</font><br /><br />" . PHP_EOL;
    }
    else {

        echo '<font color="red">' . htmlspecialchars($pattern) . ' ==> ' . $string . " 은 패턴에 매치되는 문자열을 포함하지 않은 문자열 입니다.</font><br /><br />" . PHP_EOL;
    }
}

?>


결과 :

/[a-z]{3}/ ==> zOOzoOZOozooZooZOO 은 패턴에 매치되는 문자열을 포함한 문자열 입니다.
ozo

/[A-Z]{3}/ ==> zOOzoOZOozooZooZOO 은 패턴에 매치되는 문자열을 포함한 문자열 입니다.
OZO

/[a-zA-Z]{3}/ ==> zOOzoOZOozooZooZOO 은 패턴에 매치되는 문자열을 포함한 문자열 입니다.
zOO

/[a-z]{3}/i ==> zOOzoOZOozooZooZOO 은 패턴에 매치되는 문자열을 포함한 문자열 입니다.
zOO

/[A-Z]{3}/i ==> zOOzoOZOozooZooZOO 은 패턴에 매치되는 문자열을 포함한 문자열 입니다.
zOO

/zoo/ ==> zOOzoOZOozooZooZOO 은 패턴에 매치되는 문자열을 포함한 문자열 입니다.
zoo

/ZOO/ ==> zOOzoOZOozooZooZOO 은 패턴에 매치되는 문자열을 포함한 문자열 입니다.
ZOO

/[zZ][oO][oO]/ ==> zOOzoOZOozooZooZOO 은 패턴에 매치되는 문자열을 포함한 문자열 입니다.
zOO

/zoo/i ==> zOOzoOZOozooZooZOO 은 패턴에 매치되는 문자열을 포함한 문자열 입니다.
zOO

/ZOO/i ==> zOOzoOZOozooZooZOO 은 패턴에 매치되는 문자열을 포함한 문자열 입니다.
zOO



2. s
이것은 패턴 내의 . 메타 문자에 대하여 \n(개행문자) 를 포함하겠다 는 뜻입니다.
이전 내용에서 . 메타 문자아무 문자나 하나 를 가리킨다고 하였습니다.
그러나, 이것을 좀 더 정확히 표현하자면 \n(개행문자) 를 제외한 모든 문자중 하나 입니다.
즉, . 메타문자에 \n 도 포함하여 사용할려면 s 패턴변경자와 같이 쓰여져야 합니다.

예제19> test19.php

<?php

$string = "I am a boy.
You are a girl?";

$patterns = Array();
$patterns[] = "/^.+/"// \n 을 제외한 모든 문자를 찾는다.
$patterns[] = "/^.+/s"// s 패턴 변경자를 사용하여 \n 을 포함한 모든 문자를 찾는다.
$patterns[] = "/^[^!]+/"// !를 제회한 모든 문자를 찾는다.
$patterns[] = "/^.+$/"// \n 을 제외한 모든 문자를 찾는다.
$patterns[] = "/^.+$/s"// s 패턴 변경자를 사용하여 \n 을 포함한 모든 문자를 찾는다.
$patterns[] = "/^[^!]+$/"// !를 제회한 모든 문자를 찾는다.

foreach($patterns as $pattern){

    if (preg_match($pattern, $string, $m)) {

        echo '<font color="blue">' . htmlspecialchars($pattern) . ' ==> ' . $string . " 은 패턴에 매치되는 문자열을 포함한 문자열 입니다. <br> " . nl2br($m[0]) . "</font><br /><br />" . PHP_EOL;
    }
    else {

        echo '<font color="red">' . htmlspecialchars($pattern) . ' ==> ' . $string . " 은 패턴에 매치되는 문자열을 포함하지 않은 문자열 입니다.</font><br /><br />" . PHP_EOL;
    }
}

?>


결과 :

/^.+/ ==> I am a boy.You are a girl? 은 패턴에 매치되는 문자열을 포함한 문자열 입니다.
I am a boy.


/^.+/s ==> I am a boy.You are a girl? 은 패턴에 매치되는 문자열을 포함한 문자열 입니다.
I am a boy.
You are a girl?

/^[^!]+/ ==> I am a boy.You are a girl? 은 패턴에 매치되는 문자열을 포함한 문자열 입니다.
I am a boy.
You are a girl?

/^.+$/ ==> I am a boy.You are a girl? 은 패턴에 매치되는 문자열을 포함하지 않은 문자열 입니다.

/^.+$/s ==> I am a boy.You are a girl? 은 패턴에 매치되는 문자열을 포함한 문자열 입니다.
I am a boy.
You are a girl?

/^[^!]+$/ ==> I am a boy.You are a girl? 은 패턴에 매치되는 문자열을 포함한 문자열 입니다.
I am a boy.
You are a girl?

※ 예제 결과에서 첫번째 결과와 네번째 결과를 비교해 보면 패턴은 각각 /^.+/ /^.+$/ 입니다.
그런데, 첫번째는 결과가 있고, 두번째는 결과가 없습니다.
패턴의 차이는 $ 가 붙었나 안 붙었나의 차이입니다.
즉, 이것은 s 패턴변경자가 없기 때문에 . 메타문자는 \n 을 포함하지 않습니다.
따라서 원래의 문자열에 \n 이 포함되어있기 때문에 $ 가 붙으면 끝까지 일치 하는 것이므로 네번째는 결과가 없는 것입니다.

/^[^!]+/ 이 패턴을 예제에 넣은 이유는 . 메타문자와 ^ 과 함께 사용되는 문자클래스를 비교 하기 위함입니다.
. 은 s 패턴변경자에 따라 \n 문자를 포함하지만, ^ 과 함께 사용된 문자클래스는 지정된 문자를 제외한 모든 문자이므로
문자클래스에 \n을 포함하지 않았다면 당연히 \n 을 포함하여 검사합니다.



3. m
이것은 주어진 문자열을 여러줄로 취급 하여 검사 하겠다 는 것입니다.
문자열의 시작을 나타내는 ^ 나 문자열의 끝을 나타내는 $ 와 같이 사용될때만 의미 가 있습니다.
즉, ^ 과 $의 의미가 변하게 됩니다.
^ 은 전체 문자열의 시작을 의미하지 않고 줄(line)의 시작 을 의미합니다.
반대로 $ 은 전체 문자열의 끝을 의미하지 않고 줄(line)의 끝 을 의미합니다.

m 패턴변경자를 사용하지 않았다면 주어진 문자열이 여러줄이라도 한줄로 취급합니다.
즉, \n (개행문자) 를 하나의 문자로 취급한다는 것이지 줄바꿈을 해주는 개행문자로 취급하지 않는다는 뜻 이기도 합니다.


예제20> test20.php

<?php

$string = "I am a boy.
You are a girl?
I am a student.
You are a student too?";

$patterns = Array();
$patterns[] = "/^I.+$/"// 첫글자가 I 인것을 찾는다.
$patterns[] = "/^Y.+$/"// 첫글자가 Y 인것을 찾는다.
$patterns[] = "/^I.+$/s"// s 패턴 변경자를 사용하여 첫글자가 I 인것을 찾는다.
$patterns[] = "/^Y.+$/s"// s 패턴 변경자를 사용하여 첫글자가 Y 인것을 찾는다.
$patterns[] = "/^I.+$/m"// m 패턴 변경자를 사용 하여 첫글자가 I인것을 찾는다.
$patterns[] = "/^Y.+$/m"// m 패턴 변경자를 사용 하여 첫글자가 Y인것을 찾는다.
$patterns[] = "/^I.+$/ms"// m 과 s 패턴 변경자를 사용 하여 첫글자가 I인것을 찾는다.
$patterns[] = "/^Y.+$/ms" ; // m 과 s 패턴 변경자를 사용 하여 첫글자가 Y인것을 찾는다.
$patterns[] = "/^I.+/"// 첫글자가 I 인것을 찾는다.
$patterns[] = "/^Y.+/"// 첫글자가 Y 인것을 찾는다.
$patterns[] = "/^I.+/s" ; // s 패턴 변경자를 사용하여 첫글자가 I 인것을 찾는다.
$patterns[] = "/^Y.+/s"// s 패턴 변경자를 사용하여 첫글자가 Y 인것을 찾는다.
$patterns[] = "/^I.+/m"// m 패턴 변경자를 사용 하여 첫글자가 I인것을 찾는다.
$patterns[] = "/^Y.+/m"// m 패턴 변경자를 사용 하여 첫글자가 Y인것을 찾는다.
$patterns[] = "/^I.+/ms" // m 과 s 패턴 변경자를 사용 하여 첫글자가 I인것을 찾는다.
$patterns[] = "/^Y.+/ms"// m 과 s 패턴 변경자를 사용 하여 첫글자가 Y인것을 찾는다.

foreach($patterns as $pattern){

    if (preg_match($pattern, $string, $m)) {

        echo '<font color="blue">' . htmlspecialchars($pattern) . ' ==> ' . $string . " 은 패턴에 매치되는 문자열을 포함한 문자열 입니다.<br>" . nl2br($m[0]) . "</font><br /><br />" . PHP_EOL;
    }
    else {

        echo '<font color="red">' . htmlspecialchars($pattern) . ' ==> ' . $string . " 은 패턴에 매치되는 문자열을 포함하지 않은 문자열 입니다.</font><br /><br />" . PHP_EOL;
    }
}

?>


결과 :

/^I.+$/ ==> I am a boy.You are a girl?I am a student.You are a student too? 은 패턴에 매치되는 문자열을 포함하지 않은 문자열 입니다.

/^Y.+$/ ==> I am a boy.You are a girl?I am a student.You are a student too? 은 패턴에 매치되는 문자열을 포함하지 않은 문자열 입니다.

/^I.+$/s ==> I am a boy.You are a girl?I am a student.You are a student too? 은 패턴에 매치되는 문자열을 포함한 문자열 입니다.
I am a boy.
You are a girl?
I am a student.
You are a student too?

/^Y.+$/s ==> I am a boy.You are a girl?I am a student.You are a student too? 은 패턴에 매치되는 문자열을 포함하지 않은 문자열 입니다.

/^I.+$/m ==> I am a boy.You are a girl?I am a student.You are a student too? 은 패턴에 매치되는 문자열을 포함한 문자열 입니다.
I am a boy.


/^Y.+$/m ==> I am a boy.You are a girl?I am a student.You are a student too? 은 패턴에 매치되는 문자열을 포함한 문자열 입니다.
You are a girl?


/^I.+$/ms ==> I am a boy.You are a girl?I am a student.You are a student too? 은 패턴에 매치되는 문자열을 포함한 문자열 입니다.
I am a boy.
You are a girl?
I am a student.
You are a student too?

/^Y.+$/ms ==> I am a boy.You are a girl?I am a student.You are a student too? 은 패턴에 매치되는 문자열을 포함한 문자열 입니다.
You are a girl?
I am a student.
You are a student too?

/^I.+/ ==> I am a boy.You are a girl?I am a student.You are a student too? 은 패턴에 매치되는 문자열을 포함한 문자열 입니다.
I am a boy.


/^Y.+/ ==> I am a boy.You are a girl?I am a student.You are a student too? 은 패턴에 매치되는 문자열을 포함하지 않은 문자열 입니다.

/^I.+/s ==> I am a boy.You are a girl?I am a student.You are a student too? 은 패턴에 매치되는 문자열을 포함한 문자열 입니다.
I am a boy.
You are a girl?
I am a student.
You are a student too?

/^Y.+/s ==> I am a boy.You are a girl?I am a student.You are a student too? 은 패턴에 매치되는 문자열을 포함하지 않은 문자열 입니다.

/^I.+/m ==> I am a boy.You are a girl?I am a student.You are a student too? 은 패턴에 매치되는 문자열을 포함한 문자열 입니다.
I am a boy.


/^Y.+/m ==> I am a boy.You are a girl?I am a student.You are a student too? 은 패턴에 매치되는 문자열을 포함한 문자열 입니다.
You are a girl?


/^I.+/ms ==> I am a boy.You are a girl?I am a student.You are a student too? 은 패턴에 매치되는 문자열을 포함한 문자열 입니다.
I am a boy.
You are a girl?
I am a student.
You are a student too?

/^Y.+/ms ==> I am a boy.You are a girl?I am a student.You are a student too? 은 패턴에 매치되는 문자열을 포함한 문자열 입니다.
You are a girl?
I am a student.
You are a student too?

※ 첫번째 /^I.+$/ 패턴은 대문자 I 로 시작하면서 \n을 제외한 모든 문자로만 끝까지 이루어진 문자열을 매치 합니다.
따라서 주어진 문자열에는 \n 이 포함되어 있으므로 매치된 결과가 없는 것입니다.

두번째 /^Y.+$/ 패턴은 대문자 Y 로 시작하는 것을 찾는것을 제외하면 첫번째 패턴과 동일합니다.

다섯번째 /^I.+$/m 패턴은 m 패턴변경자를 사용함 으로써 ^ 과 $ 이 줄의 시작과 끝 을 가리키게 되므로 I am a boy. 가 매치되었습니다.

일곱번째 /^I.+$/ms 패턴은 m 과 s 패턴변경자 두개를 동시에 사용 하였습니다.
의미가 다른 패턴 변경자는 여러개를 동시에 사용할수 있습니다.
그런데, 여기서 보면 m 패턴변경자를 사용하였으므로 $ 은 줄의 끝을 가리키는 것인데, 결과값은 4줄 모두 나왔습니다.
그 이유는 정규표현식은 매치되는 문자열을, 최대로 매치되는 범위 모두를 잡기 때문에 그렇습니다.
s 패턴 변경자를 사용하였기 때문에 \n 도 . 메타문자에 포함되고 맨끝도 라인의 끝이 되므로 모두 매치되는 것입니다.

아홉번째 이하는 $ 의 있고 없고의 차이를 보여주기 위한 예제입니다.
|

댓글 20개

잘보겠습니다 꾸벅
네 감사합니다. 일번이네요.
좋아요 좋아요
고맙습니다.
시간은 없고, 일단 찜해두자는 의미에서 추천만......ㅎ
음~ 크롬에서는 추천이 안되는군요... 다시 익스로 들어와서 추천!!
고맙습니다. 도레미님.
감사합니다.~
어 그래 고맙다.
ㅎㅎㅎㅎㅎ
잘 봤습니다...
항상 챙겨 봐 줘서 고맙습니다.
쉽게 잘 설명해 주셨네요. 나린위키 파서 만들때 정규 표현식땜에 고생좀 했었는데.. 새록새록 기억이 다시 납니다 ^^
네에 고맙습니다.

예전에 깊게는 못보고 언뜻 나린위키 파서를 훓어 본거 같은데.
아주 잘 만들었던 것 같습니다.
/m 은 처음 알게 되었네요.
2라인 이상일 때 시작(^), 종료($) 메타 문자의 범위를
현재 라인에서 전체 라인으로 범위를 확대해주는 역활이군요.

잘 봤습니다.
네에
말씀 하신 것과 반대의 의미 입니다.
m 을 사용하게 되면
^ 은 라인의 시작
$ 은 라인의 끝을 의미 합니다.

좋게 봐주셔서 감사합니다.
한동안 강좌가 올라오지 않아서 끝났나 했더니 다시 시작됐네요.
감사합니다.
개인적인 사정으로
제가 시간 날때 한번씩 올립니다.
감사합니다.
패턴변경자는 i 밖에 몰랐는데 s 랑 m 도 있다는걸 배웠네요..
좋은강좌 감사합니다 ^^
아직 패턴변경자 1이라서 세개만 설명했습니다.

나중에 패턴변경자 2가 있습니다.
수고하셨습니다.
댓글을 작성하시려면 로그인이 필요합니다. 로그인

프로그램

태그 필터 (최대 3개) 전체 개발자 소스 기타 mysql 팁자료실 javascript php linux flash 정규표현식 jquery node.js mobile 웹서버 os 프로그램 강좌 썸네일 이미지관련 도로명주소 그누보드5 기획자 견적서 계약서 기획서 마케팅 제안서 seo 통계 서식 통계자료 퍼블리셔 html css 반응형 웹접근성 퍼블리싱 표준화 반응형웹 홈페이지기초 부트스트랩 angularjs 포럼 스크린리더 센스리더 개발자톡 개발자팁 퍼블리셔톡 퍼블리셔팁 기획자톡 기획자팁 프로그램강좌 퍼블리싱강좌
+
제목 글쓴이 날짜 조회
12년 전 조회 1.4만
12년 전 조회 1,242
12년 전 조회 653
12년 전 조회 3,971
12년 전 조회 1,492
12년 전 조회 9,388
12년 전 조회 824
12년 전 조회 1,279
12년 전 조회 3,258
12년 전 조회 883
12년 전 조회 1,802
12년 전 조회 3,689
12년 전 조회 1,110
12년 전 조회 1,002
12년 전 조회 5,341
12년 전 조회 1,468
12년 전 조회 798
12년 전 조회 2,740
12년 전 조회 2,526
12년 전 조회 1,543
12년 전 조회 2,978
12년 전 조회 6,586
12년 전 조회 2,180
12년 전 조회 781
12년 전 조회 1,940
12년 전 조회 1,894
12년 전 조회 2,643
12년 전 조회 636
12년 전 조회 1,725
12년 전 조회 810
12년 전 조회 1,807
12년 전 조회 2,726
12년 전 조회 1,284
12년 전 조회 3,916
12년 전 조회 9,997
12년 전 조회 1,155
12년 전 조회 2,485
12년 전 조회 2,158
12년 전 조회 3,021
12년 전 조회 6,056
12년 전 조회 2,675
12년 전 조회 2,995
12년 전 조회 1,004
12년 전 조회 804
12년 전 조회 1,885
12년 전 조회 5,898
12년 전 조회 1,503
12년 전 조회 4,737
12년 전 조회 969
12년 전 조회 4,137
12년 전 조회 1,279
12년 전 조회 1,136
12년 전 조회 1,714
12년 전 조회 1,349
12년 전 조회 601
12년 전 조회 573
12년 전 조회 2만
12년 전 조회 540
12년 전 조회 1,106
12년 전 조회 1,110
12년 전 조회 1,353
12년 전 조회 3,500
12년 전 조회 735
12년 전 조회 2,238
12년 전 조회 4,919
12년 전 조회 689
12년 전 조회 3,878
12년 전 조회 1,069
12년 전 조회 3,796
12년 전 조회 946
13년 전 조회 1,793
13년 전 조회 961
13년 전 조회 2,185
13년 전 조회 7,969
13년 전 조회 1,956
13년 전 조회 1,752
13년 전 조회 1,568
13년 전 조회 627
13년 전 조회 2,146
13년 전 조회 1,875
13년 전 조회 661
13년 전 조회 1,231
13년 전 조회 646
13년 전 조회 933
13년 전 조회 1,221
13년 전 조회 3,608
13년 전 조회 2,140
13년 전 조회 2,329
13년 전 조회 3,697
13년 전 조회 3,510
13년 전 조회 3,169
13년 전 조회 4,039
13년 전 조회 1,052
13년 전 조회 6,015
13년 전 조회 1,405
13년 전 조회 1,247
13년 전 조회 3,432
13년 전 조회 3,063
13년 전 조회 5,216
13년 전 조회 2,720
🐛 버그신고