정규표현식 의 핵심. 패턴변경자 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,235
12년 전 조회 643
12년 전 조회 3,968
12년 전 조회 1,490
12년 전 조회 9,379
12년 전 조회 817
12년 전 조회 1,273
12년 전 조회 3,251
12년 전 조회 880
12년 전 조회 1,799
12년 전 조회 3,682
12년 전 조회 1,106
12년 전 조회 997
12년 전 조회 5,335
12년 전 조회 1,464
12년 전 조회 790
12년 전 조회 2,740
12년 전 조회 2,521
12년 전 조회 1,536
12년 전 조회 2,973
12년 전 조회 6,578
12년 전 조회 2,176
12년 전 조회 773
12년 전 조회 1,936
12년 전 조회 1,890
12년 전 조회 2,639
12년 전 조회 630
12년 전 조회 1,722
12년 전 조회 804
12년 전 조회 1,802
12년 전 조회 2,720
12년 전 조회 1,274
12년 전 조회 3,911
12년 전 조회 9,992
12년 전 조회 1,147
12년 전 조회 2,479
12년 전 조회 2,152
12년 전 조회 3,015
12년 전 조회 6,050
12년 전 조회 2,670
12년 전 조회 2,992
12년 전 조회 999
12년 전 조회 795
12년 전 조회 1,882
12년 전 조회 5,889
12년 전 조회 1,499
12년 전 조회 4,732
12년 전 조회 963
12년 전 조회 4,129
12년 전 조회 1,274
12년 전 조회 1,132
12년 전 조회 1,711
12년 전 조회 1,345
12년 전 조회 596
12년 전 조회 569
12년 전 조회 2만
12년 전 조회 535
12년 전 조회 1,099
12년 전 조회 1,106
12년 전 조회 1,347
12년 전 조회 3,494
12년 전 조회 733
12년 전 조회 2,236
12년 전 조회 4,913
12년 전 조회 686
12년 전 조회 3,872
12년 전 조회 1,062
12년 전 조회 3,790
12년 전 조회 942
13년 전 조회 1,789
13년 전 조회 954
13년 전 조회 2,180
13년 전 조회 7,967
13년 전 조회 1,950
13년 전 조회 1,745
13년 전 조회 1,563
13년 전 조회 622
13년 전 조회 2,141
13년 전 조회 1,870
13년 전 조회 658
13년 전 조회 1,226
13년 전 조회 638
13년 전 조회 930
13년 전 조회 1,220
13년 전 조회 3,603
13년 전 조회 2,138
13년 전 조회 2,322
13년 전 조회 3,695
13년 전 조회 3,507
13년 전 조회 3,163
13년 전 조회 4,036
13년 전 조회 1,047
13년 전 조회 6,010
13년 전 조회 1,400
13년 전 조회 1,239
13년 전 조회 3,429
13년 전 조회 3,059
13년 전 조회 5,211
13년 전 조회 2,718
🐛 버그신고