PHP에서의 정규식 > PHP

본문 바로가기
사이트 내 전체검색

PHP

PHP에서의 정규식

페이지 정보

profile_image
작성자 최고관리자
댓글 0건 조회 7,553회 작성일 21-02-09 11:51

본문

출처 : http://www.jigi.net/3911  (지기닷넷)

또다시 오랜만 이군요...
오늘은 정규표현식에 대해 간단하게 알아보는 시간을 갖도록 하겠습니다.

정규표현식(Regular Expressions)라는 말은 자주들 들어 보셨을 겁니다.
보통 정규식이라고 줄여서 부르기도 하는데요...
이건 뭐 -_-a사람 이름도 아니고 말이죠....-.-규식아~~
암튼...
정규표현식이라는건 대체 뭘까요?

말 그대로 어떤 내용에 대하여 정규화된 표현식을 말합니다.
예를 들자면...

abc
 def

위와 같은 두개의 문자열이 있을때...
위의 문자열들을 정규화하여 표현하자면 어떻게 될까요?

 * 알파벳으로 이루어져 있다

 맞습니까?
맞죠...........당연한 말씀을 -_-a;;

 * 소문자 3자로 이루어져 있다

 역시 맞죠...
대충 감이 오십니까?

그럼이제 어떤 경우에 이 정규표현식이 쓰이는지 알아 볼까요?
어떤 값을 입력받는데 있어서...
반드시 영문 소문자와 숫자만을 이용하여 입력을 받아야 하는 경우가 있습니다.
어떤경우죠?
보통 회원가입에서 아이디 입력 등이 있겠군요...

정규표현식으로 만들어 볼까요?

 * 영문 소문자와 숫자의 조합 이다
* 4~12자 사이의 문자열 이다
* 공백이 있어서는 안된다

 뭐 이정도면 될까요...

이런 경우에 있어서 정규표현식이 사용되는데...
이것을 이제 컴퓨터가 알아들을 수 있는 말로 바꾸어 주어야 하겠죠..
이때 쓰이는 것이 바로 정규표현식 입니다.


정규표현식을 사용하는데에는 여러가지 용도가 있겠죠...
예를 들어 우리가 원하는 표현식과 일치 하는지 알아보기 위함이라던가...
우리가 원하는 표현식에 해당하는 부분을 치환한다던가...
아니면 우리가 원하는 표현식에 해당하는 부분을 경계로 문자열을 배열로 나눈다던가 말입니다.

먼저 우리가 원하는 표현식과 일치 하는지를 알아보기 위해서는 ereg라는 함수가 사용 됩니다.
형식은 아래와 같고요...

 $리턴값 = ereg("정규표현식","대상문자열");

대상문자열이 정규표현식과 일치한다면 TRUE가 리턴되고...
그렇지 않다면 FALSE가 리턴되겠죠...

예를 들어 볼까요?

 <?
echo ereg("b","abc");
 ?>

실행 해보세요...
결과는?

1이 나올 것입니다...
TRUE가 리턴된 것인데요...
대상문자열 abc에 b가 포함되어 있느냐는 표현식이었습니다.
물론 b가 포함되어 있으니 참이겠죠...

그럼 이제 아래와 같이 해볼까요?

 <?
echo ereg("B","abc");
 ?>

결과는 FALSE가 되어 아무것도 출력되지 않을 것입니다.
왜냐하면 abc에는 대문자B가 없기 때문이죠...
그럼 함수를 ereg가 아닌 eregi로 바꾸어 볼까요?

 <?
echo eregi("B","abc");
 ?>

어라?
결과는 다시 1 입니다.
ereg에 i를 붙여 주었더니 대소문자를 구별하지 않는 군요...
이때 i는 ignore겠죠...
말그대로 대소문자 그런거 구분 하지 않겠다는 것입니다.
대충 이해 가셨으리라 생각하고...

슬슬 표현식을 구성하는 방법에 대해 알아보도록 하죠~


정규표현식에서 가장 기본적인 것은...
시작과 끝 입니다.
시작은 ^이고 끝은 $로 표현하는데....

 * a로 시작되는 문자열

 위의 표현식은 아래와 같이 된다는 얘기 입니다.

 ^a

그럼 c로 끝나는 문자열은 어떻게 될까요?

c$

이렇게죠...
한번 확인해보도록 하죠...

 <?
echo ereg("^a","abc");
 ?>

결과는 당근 1 입니다.

이때 abc이 이외에도 ^a라는 정규표현식에 해당하는 문자열에 대해서는
 모두 TRUE겠죠...

a, aa, aaa, abb, abbbb, acccc

위의 것 모두 TRUE입니다.
모두 a로 시작하니까요...

 $도 같은 식으로 사용 하시면 되고요...
만약 ^abc$와 같이 표현식을 주시면...
abc라는 문자열만 TRUE가 됩니다...
왜 인지는 잘 생각 해보시고요~


 * b가 없거나 한번이상 반복되는 문자열

 위의 문제는 조금 어렵죠...?
b가 없거나 한번이상 반복되는 것은 어떤것을 말할까요?

ac, abc, abbc, abbbc

뭐 이런것들이겠죠...
물론 acb나 acbb와 같은 것도 모두 맞습니다만...
일단 위의 패턴만을 생각해보도록 하죠...
위의 나열된 패턴은 a로 시작되어 c로 끝나면서..
그 사이에 b가 없거나 한번이상 반복되는 것입니다.

이때 b가 없거나 한번이상 반복되는 것은 *로 표현을 하는데요...

b*와 같이 해주시면 되겠네요...
이때 *는 없거나 한번이상 반복된다는 것을 말하는데요..
바로 앖에 있는 문자만 해당합니다.

말하자만 ab*과 같이 되어있을 경우에는...
ab가 없거나 한번 이상...어쩌구가 아니라...
a가 나오고 이어서 b가 없거나 한번이상...거시기라 그말이죠..

그럼 다시 문제를 생각해볼때...

a로 시작되어서........... -> ^a
 c로 끝나면서............. -> ^ac$
 b가 없거나 한번이상 반복. -> ^ab*c$

쉽죠?^^
이 정규표현식은...
ac, abc, abbc, abbbc
와 같은 문자열을 모두 포함합니다.

이렇게 *와 같이 쓰이는 표현식중에 아래와 같은 것들도 있으니
 한번 눈여겨 보시고요~~~

 * -> 앞의 문자가 없거나 한번이상 반복
+ -> 앞의 문자가 반드시 한번이상 반복
? -> 앞의 문자가 없거나 한개만 있음

 위의 표현식들을 이용해보면 아래와 같은 결과들을 만들수 있습니다.

 ^ab*c$
 -> a로 시작되어 b가 없거나 한번이상 반복되고 c로 끝남
-> ac, abc, abbc, abbbc 등등

^ab+c$
 -> a로 시작되어 b가 한번이상 반복되고 c로 끝남
-> abc, abbc, abbbc 등등

^ab?c$
 -> a로 시작되어 b가 없거나 한개만 있고 c로 끝남
-> ac, abc (두가지 뿐임)

그런데 우리가 방금 배운 *, + ,?의 기능을 모두 해결해 줄수 있는
 표현식도 있습니다.
바로 {와 }인데요...
표현방법은 아래와 같습니다.

 {최소반복횟수,최대반복횟수}

예를 들어 b{2,3}이라고 하였다면..
b가 2번에서 3번 반복되는 것이라고 보시면 되고요...

 ^ab{2,3}c$

위와 같은 식이라면...
a로 시작하여 b가 2~3번 반복되고 c로 끝나는 문자열이 되겠네요..
abbc, abbbc 이렇게 두가지경우가 있겠죠...
그런데 이를 약간 변형하여...

b{2}

이렇게 써준다면..
b는 반드시 2번 반복된다는 것이 되고...

b{2,}

이렇게 써준다면...
b는 2번 이상이 되고...

b{0,2}

요건 2번 이하가 되겠죠....
b{,2}가 아님에 주의 하세요...

그럼 {와 }를 이용하여... *, +, ?를 흉내내 볼까요?-0-

*은 앞의 문자가 없거나 한번이상 반복이기 때문에 -> {0,}
 + -> 앞의 문자가 반드시 한번이상 반복이기 때문에 -> {1,}
 ? -> 앞의 문자가 없거나 한개만 있음이기 때문에 -> {0,1}

요롷게 됩니다...
이해 안가시는 분들은 SHIFT+SPACE를 눌러 주세요 -_,-

자 그럼....
좀더 재미있는 것을 배워 볼까요?+_+/

 * a로 시작하여 d로 끝나는데...a와 d사이에는 bc가 두번에서 세번 나올수 있다

 위의 명제를 정규표현식으로 바꾸어 보도록 하죠...

a로 시작하여 -> ^a
 d로 끝나는데 -> d$
 a와 d사이에는 bc가 두번에서 세번 나올수 있다 -> ?????? -_-a

두번에서 세번은 {2,3}으로 하면 되겠는데...
bc를 동시에 붙잡자니 막막 하시죠...

이럴경우에 사용되는 것이 (와 )입니다. -_,-a알려드리는걸 깜박 했군요;;

 (bc) 요롷게 두개를 묶어주면...
뒤에 붙을 {2,3}의 영향을 묶여서 받게 된다 그거죠...
그러므로 (bc){2,3}과 같이 해주면...
bc가 두번에서 세번 나온다가 됩니다.
결국 완성된 식은....

 ^a(bc){2,3}c$

이렇게 되겠죠...
-_-a점점 결과물이 암호처럼 되어가는군요;;;

허나...아직 우리가 배울것은 많이 남았습니다....


 * a로 시작하여 d로 끝나는데 b또는 c가 없거나 한번 나올수 있다

 후후 -_,- "없거나"... 요부분 걸리시죠?

 ^a    d$

뭐 대충 요렇게는 짐작 하셨을 테고요...
or의 역할을 하는 것으로 |이 있습니다.
이거 어떻게 치느냐면요;;;-_-;;;
키를 SHIFT를 누른채로 눌러 주시면 |가 이쁘게 나올겁니다;;;

b또는 c라는 것은....

b|c

위와 같이 나타낼수 있다는 얘기죠...
결국 표현식은...

 ^a(b|c)?d$

이렇게 됩니다...
 (b|c)는 b또는 c가 되고...
이를 ( )로 묶어서 ?를 붙여 주었는데요...
b나 c중에 둘중 하나가 나오는데 ?가 있기 때문에..
그것이 없을 수도 있고 한번 있을 수도 있다는 것이죠...

물론 (b|c)?가 아닌 (b|c){0,1}와 같이 해주셔도 의미는 같습니다.


 * 세자로 이루어진 문자열

-_-a이번문제는 좀 막막 하시죠;;;
세자로 이루어졌다면야..
 {3} 요롷게 해주면 되겠는데...
모든 문자열을 대상으로 하다보니...-_-a;;;

이때 쓰이는 것은 . 입니다
-_-a 쩜이죠......

 .는 정규표현식에서 어떤 한 문자열이라는 의미로 사용 되는데요...

 .{3}

이렇게 하면 어떤 문자열이 세개가 있다는 것이되겠죠..
그런데 위와 같이 하면...
네자 또는 그 이상의 문자열도 모두 참이 됩니다...
왜냐하면.....
네자로 이루어진 문자열도 세자는 포함하고 있고...
다섯자로 이루어진 문자열도 역시 세자 정도는 포함하고 있으니 말이죠..
그렇기 때문에 딱 세자로만 이루어진 문자열을 표현하고자 한다면...
아래와 같이 해주셔야 합니다.

 ^.{3}$

왜 그래야만 하는지를 모르신다면...
-_,- SHIFT+SPACE를...


이렇게도 만들어 볼수가 있겠죠...

 * a로 시작하여 2~3개의 문자가 있고 c로 끝나는 문자열

 차근차근 살펴보죠....
어려운건 아닙니다...

a로시작하여 -> ^a
 2~3개의 문자가 있고 -> .{2,3}
 c로 끝나는 문자열 -> c$

합쳐보면...

 ^a.{2,3}c$

이렇게 됩니다...


자 그럼 다음문제는...

 * 1부터 5까지중의 숫자로만 이루어진 문자열

 조금 난해하죠?;;

먼저 1부터 5까지라면...
 (1|2|3|4|5)
뭐 이렇게 하면 될까요...

 ^(1|2|3|4|5)$

이렇게 해주면 1부터 5까지의 숫자중 하나의 숫자로
 이루어진 문자가 됩니다...맞죠?
그런데 문제에서는 문자열이 될수 있다 하였으니...

 ^(1|2|3|4|5)+$

이렇게 해주면 될것 같군요...
 +는 하나 또는 그 이상을 뜻하는 것이니...
명제에 일치하는 식이 되겠죠...

쉽네요^^
그럼 다음 문제를 볼까요?

 * 영문소문자로만 이루어진 문자열

-_-a;;;
어쩌시렵니까...

 ^(a|b|c| 중간생략 |x|y|z)$

뭐 이렇게 하실까요;;;

-_,-이럴때 쓰는 간단한 방법이 있지요...

이럴경우에 우리는 []를 사용하여...
문자셋의 범위를 정해줄수가 있는데요...

만약 0부터 5까지라고 하였다면...

 [0-5]

이렇게만 해주면 됩니다.
또한 영문소문자라면...

 [a-z]

이렇게 되는거죠...
결국 영문소문자로만 이루어진 문자열이라 하면...

 ^[a-z]+$

이렇게 간단하게 끝나는 겁니다.
쉽죠?^^

아래 예제를 통해 어떤방식으로 []가 사용되는지 일단 살펴들 보시고요..

 [0-9] -> 0에서 9까지의 숫자
[a-z] -> a에서 z까지의 소문자
[A-Z] -> A에서 Z까지의 대문자
[a-zA-Z] -> 소문자a부터 대문자Z까지
[0-9a-z] -> 0에서 9까지 또는 a에서 z까지
[0-9-] -> 0에서 9까지 또는 -
[a-z_] -> a에서 z까지 또는 _

위에서와 같이 []안에 포함되어 있는 문자 또는 범위에 대해
 어떤문자가 허용될 것인지를 정해줄수가 있는데요..
만약 위에서와 같이 - 를 그 대상에 포함하려면...
가장 처음이나 가장 마지막에 - 를 위치 시켜야만 합니다.


 * a,c,d,f중의 두문자로만 이루어진 문자

 답은?

 ^[acdf]{2}$

이렇게 해도 된다는 것이죠...
위의 정규표현식에는...
aa,ac,dc,fa 모두 참이 됩니다.
 []안의 문자중에 있는 문자로 이루어진 2자의 문자열이면 모두 참이니까요..


 * 영문소문자 또는 숫자 또는 - 또는 _ 로만 이루어진 4자이상 12자 이하의 아이디


 이번 문제는 좀 복잡해 보이죠?
뭐 근데 차근차근 보면 그리 어렵지 않을 겁니다...

영문소문자 -> [a-z]
또는 숫자 -> [a-z0-9]
또는 -    -> [a-z0-9-]
또는 _    -> [a-z0-9-_]

그런데 이렇게 하면 에러 납니다-_-;;
위에서 언급했듯이...
-는 범위를 나타내는 기호가 되기 때문에...
가장 처음이나 가장 끝에 위치 시켜야 합니다..
그래서 아래와 같이 해주어야만 에러가 나지 않겠죠

[a-z0-9_-]

아래와 같이 해도 됩니다.

 [-a-z0-9_]

 4자이상 12자 이하이기 때문에...

 ^[a-z0-9_-]{4,12}$

이렇게 되겠죠...
위와 같은 정규표현식은...
보통 회원아이디 가입시에 입력한 아이디의 형식을 체크할때 사용됩니다...

 <?
 $id="Navyism_1-1";
 echo eregi("^[a-z0-9_-]{4,12}$",$id);
 ?>

위 소스를 실행해 보세요...
결과는?-_,-

어라 1이나오네요...-_-a이상하죠?
분명 우리는 영문소문자를 허용하도록 해두었는데...
 $id에는 대문자 N이 있음에도 불구하고 TRUE값이 나왔습니다.

왜 그랬을까요?

문제는 eregi라는 함수에 있는것이죠...
위에서 말씀드렸듯이..
ereg는 대소문자를 구분하지만...
eregi는 구분하지 않습니다.
그렇기 때문에 우리는 정규표현식에 소문자를 허용하도록 해두었더라도
 함수 자체에서 그것을 무시해 보리기 때문에 이런 결과가 나오는 것이겠죠...

 <?
 $id="Navyism_1-1";
 echo ereg("^[a-z0-9_-]{4,12}$",$id);
 ?>

위와 같이 eregi대신 ereg를 쓰시면 FALSE가 될겁니다.

반대로 이메일주소나 홈페이지 주소와 같이...
대소문자 구분이 필요 없을 경우에는 eregi함수를 사용하는 것이
 훨씬 더 유용하겠죠..
굳이 정규표현식내에 대소문자를 모두 허용하도록 해줄 필요가 없을 테니 말이죠


* a로 시작하고 c로 끝나면서 b를 포함하지 않는 4자의 문자열

 어떤 것들이 있을까요??

aaac
 acdc
 adfc

뭐 기타 등등 많겠죠...

이번에 새로 등장한 부분은 무엇무엇을 포함하지 않는다 입니다.
이것은 [^]로 표현할 수가 있는데요...

 [^와 ] 사이에 포함하지 않을 문자를 넣어 주면 됩니다.
b를 포함하지 않는다고 하였으니...

 [^b]

이렇게 해주면 되겠군요...

a로 시작하고 -> ^a
 c로 끝나면서 -> ^ac$
 b를 포함하지 않으며 -> ^a[^b]c$
 4자의 문자열 -> ^a[^b]{2}c$

 a와 c가 각각 한자씩 모두 두자를 차지하고 있으니...
b가 아닌 문자열은 두자가 되어 {2}를 적어준 것입니다.


 * 숫자를 포함하지 않는 문자열

 간단하죠?

 ^[^0-9]+$

이렇게 됩니다...
만약 앞의 ^과 뒤의 $를 적어주지 않는다면...

1ab2

위와 같은 문자열도 참이 됩니다.
왜냐하면...

 [^0-9]+라는 것은...
숫자가 아닌 문자가 한개 또는 그 이상이 있다는 것인데...

1ab2안에는 ab라는...그 조건에 해당하는 문자가 포함되어 있기에
 결과는 참이 되는 것입니다.
그것을 방지하기 위해...

 ^와 $를 넣어 처음부터 끝까지 라는 조건을 달아주면...

1ab2 전체를 대상으로 보기 때문에...
결과는 거짓이 되는 것이죠...


 * ?가 한개 또는 그이상 포함된 문자열

 문제에서....
포함된 문자열이라는 것은...
 ^와 $를 사용할 필요가 없는다는 얘기 입니다.
말 그대로 포함이기 때문에 그것이 문자열 전체가 아닐수도 있다는 것이죠.

정답은?

 ?+

이건가요?
 +는 한개 또는 그 이상을 말하기 때문에...
 ?가 한개 또는 그 이상이 있다 하였으니...
 ?+가 맞는것 같기는 한데...
뭔가 좀 찜찜한 구석이 있죠...

바로 ?가 그 자체로 없거나 한개 있을수 있다는 뜻을 갖고 있기 때문인데요..
이렇게 정규표현식에 쓰이는 특수문자 자체를
 나타낼 때에는 를 앞에 붙여 escape 하도록 해줄수 있습니다.

결국 위와 같이 ?+라고 하면 바로 에러 메세지를 만나실것 같고요...
아래와 같이 를 사용하여 escape하자 그말이죠...

 ?+

그 외에도...
지금까지 정규표현식에 사용되었던...
 ^$[]().?+*{} 등의 문자들도 마찬가지로...
그문자 자체를 나타내려면 앞에 를 붙여 주어야 합니다.

댓글목록

등록된 댓글이 없습니다.

회원로그인

회원가입

  • 게시물이 없습니다.

접속자집계

오늘
1,404
어제
2,555
최대
6,642
전체
1,133,074
contact : webmaster@beautipia.co.kr
Copyright © beautipia.co.kr. All rights reserved.