정규표현식이라는건 대체 뭘까요?

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

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}

요렇게 됩니다...

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


 

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

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

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

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

이럴경우에 사용되는 것이 ( 와 )입니다.

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

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

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

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


 

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

"없거나 한번" 은 ? 나 {0,1}을 쓰면 되는데 "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까지라고 하였다면, (1|2|3|4|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는 구분하지 않습니다.
끝에 붙은 "i" 가 case insensitive(대소문자 불문)를 의미하는 i 이거든요.
그렇기 때문에 우리는 정규표현식에 소문자를 허용하도록 해두었더라도
함수 자체에서 그것을 무시해 보리기 때문에 이런 결과가 나오는 것이겠죠...

<?
$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. 정수 또는 소수

100
20.3
8.52


2. 다음의 문자열들을 만족하는 정규표현식을 만들어 보세요

aB@123_yZ
DDDD@003XXX
abcd@2_efgh


아파치 모듈중에서 유용한 모듈이 많이 있는데, 그 중에 한 가지가 rewrite 모듈이다.
의외로 설치하는 방법이 간단하다. 설치가 간단한 반면에 그 기능 활용을 많다고 생각이 든다.
정규식 표현을 알면 보다 쉽게 사용하니, 먼저 정규식표현을 잘 익혀두자. rewrite 모듈을 이용하면 장점이 하나의 도메인만 있으면 서브도메인을 생성하여 각기 다른 내용의 홈페이지를 운영할 수 있다는 것이다.
photo.tt.co.kr 또는 blog.tt.co.kr, shop.tt.co.kr, intra.tt.co.kr 식으로 말이다.
굳이 다른 도메인을 써야 할 이유가 없다면 홍보에도 도움이 되는 서브도메인을 이용한 홈페이지를 만들어서 운영해 보자.
국내에서는 유일하게 오늘과내일(http://tt.co.kr)에서 이 서비스를 도입하여 웹호스팅 서비스를 하고 있다.
 
웹서버에서 아파치를 컴파일하고, php도 다시 컴파일 해 준다.
제대로 모듈이 아파치에 적용되었는지 확인하고, 네임서버에서도 * 문자로 모든 2차 네임서버에 대해서 아이피 설정만 해 두면 된다.
자~ 쉽게 따라해 보자.
 


Apache rewrite Module
 

Apache 는 추가적으로 사용할 수 있는 유용한 모듈들을 제공합니다.
Apache의 URL Rewrite 모듈을 사용하기 위한 컴파일,설치 와 httpd.conf의 설정방법 그리고 활용방법에 대해 알아보겠습니다.

Apache 다운로드 : http://www.apache.org

rewrite 모듈을 사용하기 위한 Apache 컴파일옵션

Rewrite 모듈을 쓰기위한 Apache 컴파일 옵션은 --enable-rewrite 입니다.

Configure 실행시에  --enable-rewrite 만 추가하시면 Apache에서 rewrite 모듈을 사용할 있게 됩니다.

[root@superuser root]# ./cofigure prefix=/usr/local/apache2 --enable-rewrite

[root@superuser root]# make

[root@superuser root]# make install


1. Rewrite 를 적용할 수 있는 범위

Rewrite 설정은 Server Config, Virtual Host, Directory, .htaccess 에 설정할 수 있습니다.

즉 Apache 서버 전체에 Global 설정과 특정 가상호스트에만 적용하도록 할수 있고 특정 디렉토리에만 적용시킬수도 있습니다.


2. Rewrite 모듈 지시자

RewriteEngine
설정문법 : RewriteEngine On|Off

Rewriteing 엔진을 사용할지 여부를 설정합니다. 기본설정은 당연히 Off로 되어 있으며 RewriteEngine On 으로 설정하지 않는 이상 Rewritng 엔진을 활성화 시키지 않습니다.


현재 Apache에서 실행중인 모든 RewriteRule을 비활성화 시킬 때 RewriteRule 라인을 주석처리 하기보다 RewriteEngin Off 로 설정하는 것이 더 간편하고 올바른방법입니다.


RewreteLog
설정문법 : RewriteLog FILE-PATH

RewriteLog 지시자는 Rewrite 엔진의 로그를 그록할 파일을 지정합니다.
RewriteLog 파일을 항상 남기기 보다 잘못된 Rewrite 규칙들을 디버킹할 때 사용하기를 권장합니다. 아파치와 마찬가지로 RewriteLog 파일도 방문자수가 많은사이트에서는 감당못할 정도의 로그파일을 남기기 때문에 시스템 여유공간이 많이 없는 시스템에서는 해당 파티션의 하드사용률 100%로 인한 재앙(?)을 불러올수도 있습니다. 다음강좌에서 소개될 로그파일 분석에서 언급하겠지만 로그파일은 유용한 디버깅 도구가 될수 있지만 잘못 관리하면 시스템의 치명적인 악으로 존재할수도 있습니다.

RewriteLog 지시자는 반드시 RewriteLogLevel 지시자와 함께 사용하여야 됩니다.


RewriteLogLevel
설정문법 : RewriteLogLevel Level

RewriteLogLevel 지시자는 RewriteLog 지시자로 설정한 로그파일에 기록할 로그들에 대해 얼마나 자세한 내용을 로그로 남길것인가에 대해 설정하는 지시자입니다.

기록할 로그 Level 은 0 ~ 9까지 사용할 수 있으며 0은 로그를 기록하지 않겠다는 의미입니다. Level 숫자가 높을수록 자세한 로그를 기록합니다


RewriteCond
설정문법 : RewriteCond TestStirng CondPattern

RewriteCond 지시자는 RewriteRule 과 함께 사용되는 규칙으로 RewriteCond 다음에 오는 RewriteRule은 RewrieteCond 에서 설정한 패턴과 일치해야지만 RewriteRule들을 실행한다.


RewriteRule
설정문법 : RewriteRule Pattern Substitution

Rewrite 모듈의 실질적인 Rewrite 규칙들을 적용하는 지시자입니다.

Pattern(Input URL) 을 Subtitution(Return URL)로 변경하기 위한 모든 규칙들은 이 지시자를 사용해서 설정해야 됩니다.

Pattern(Input URL) 에는 Perl 정규표현식을 사용할수 있기 때문에 Input URL 의 규칙을 유연하게 적용할 수 있습니다. 이 강좌에서는 기초적인 정규표현식 사용방법만 다루고 정규표현식에 대해 자세히 알고 싶으신 분은 정규표현식에 대한 강좌나 인터넷 문서를 참고하시기 바랍니다.


정규표현식 기초

. : 다수의 한문자

? : 0개 이상의 한문자

* : 0개 이상의 문자 또는 문자열

+ : 1개 이상의 문자 또는 문자열

(chars) : (, ) 안의 문자또는 문자열을 그룹으로 묶습니다. 이 문자그룹은 Substitution(return URL)에서 $N 의 변수로 활용할수 있습니니다.

^ : 문자열의 첫문(열)을 지정합니다.

$ : 문자열의 끝 문자(열)을 지정합니다.

\(역슬래쉬) : 정규표현식에서 특별한 의미로 사용되는 문자의 특수기능을 제거합니다.(예:(, ), [, ] . 등)

{n} : 정확히 n번 반복

{n,} : n번 이상 반복

{n,m} : n 이상 m 이하 반복

[chars] : 문자들의 범위 또는 표현할 수 있는 문자들을 설정합니다.
예) [a-z] : a 부터 z 까지의 소문자, [tT] : 소문자 t 또는 대문자 T


정규표현식 단축표현들

[:alpha:] : 알파벳. [a-zA-Z] 와 같은 표현

[:alnum:] : 알파벳과 숫자. [a-zA-Z0-9] 와 같은 표현

[:digit:] : 숫자 [0-9] 와 같은 표현

[:upper:] : 대문자. [A-Z] 와 같은 표현


RewriteRule 플래그

forbidden|F : 요청하는 페이지를 403 에러로 redirect 시킵니다. RedirectRule 이 적용되고 있는 페이지를 일시적으로 사용중단을 시키거나 사용자로 하여금 페이지 접근을 할수 없게 할 때 사용합니다.

예) RewriteRule ^/test /home/blog/html/test.php [F]

사용자가 /test 로 접근할 경우 403 에러를 보냅니다.

gone|G : 요청하는 페이지를 410 에러로 redirect 시킵니다. 410 에러는 페이지가 사라젔거나 존재하지 않는다는 메시지입니다. 이것도 forbidden 과 마찬가지로 RedirectRule 이 적용되던 페이지를 일시적으로 중단시킬 때 유용하게 사용할 수 있습니다.

last|L : 이 플래그가 적용되면 뒤에 어떤 룰이 있더라도 이룰 아래의 규칙들은 적용되지 않고 RewriteRule 을 빠져나가게 됩니다. C, Perl, PHP 프로그램에서 루프를 빠져나가는 break 와 같은 의미를 가집니다.

chain|C : 이 플래그의 결과를 다음 RewriteRule 의 input 값으로 사용합니다.
예)

RewriteRule ^(.+) %{HTTP_HOST}$1 [C]

RewriteRule ^([^.]+)\.domain\.com(.*) /home/$1/public_html$2


이 룰은 사용자 홈의 도메인을 2차 도메인으로 자동설정해 줄 때 많이 쓰는 룰입니다. RewriteRule의 input은 도메인을 제외한 URI 를 인식하기 때문에 도메인까지 인식을 시켜서 다음 RewriteRule 로 체크를 하기 위해 사용한 것입니다.

http://user_id.domain.com/hello.html 이란 요청이 들어오면  /home/user_id/public_html/hello.html 로 redirect 시켜줍니다. 위와 같이 2차 도메인을 이용해 계정 사용자의 홈을 지정하기 위해서는 DNS 세팅이 선행되어야 됩니다.


RwriteRule 설정예


1. http://yourdomain.com/user_id  ->  http://yourdomain.com/home.php?id=user_id


RewriteRule ^/([a-zA-Z0-9])$   /home/user_id/public_html/home.php?id=$1

설명 : 도메인(http://yourdomain.com) 뒤에 오는 영문숫자로된 문자열을 지정하면서 그룹으로 묶었습니다. 이렇게 그룹으로 설정된 문자열 Pattern 은 Substitution(return URL) 에서 $1 이라는 변수로 받아 사용하게 됩니다. 즉 http://yourdomain.com/superuser 라는 페이지 요청이 들어오면 실제로는 http://yourdomain.com/home.php?id=superuser 라는 페이지로 redirect 시켜줍니다. 블로그나 카페(동호회) 사이트에서 블로그 사용자의 ID 로 개인 블로그 주소를 부여할 때 http://blog.com/user_id 로 부여해 주지만 실제 실행되는 파일은 이와 같이 redirect 시켜주는 경우가 많습니다.


2. http://yourdomain.com/daum  -> http://www.daum.net

RewriteRule ^/daum$  -> http://www.daum.net

설명 : http://yourdomain.com/daum 라는 페이지 요청이 들어오면 도메인이 다른 http://www.daum.net 이라는 페이지로 redirect 시켜줍니다.



RewriteOptions
설정문법 : RewriteOptions Options

현재 사용할 수 있는 option 은 MaxRedirects=number 를 사용할 수 있으며 설정된 number값에 도달하게 되면 500 Internal Server Error 를 남기고 RewriteRule을 종료합니다. 잘못된 RewriteRule에 의한 무한 루프를 방지하기 위한 목적으로 사용되는데 시스템이 이유없이 다운된다거나 할 때 이 옵션과 Log 기록을 참고하여 디버깅 및 시스템 다운을 방지할 수 있습니다.

이 지사자는 Apache 2.0.45 이상에서 사용할 수 있습니다.


3. 실제 적용예

가상호스트 blog.xxx.ac.kr 에 대해 Rewrite Rule을 적용한 예입니다. 이 부분은 실제 운영되는 블로그 사이트를 위해 RewriteRule 을 적용한 예입니다.


DocumentRoot /home/blog/html

ServerName blog.xxx.ac.kr

# 여기까지는 일반적인 가상호스트 설정입니다.

RewriteEngine on

# RewriteRule을 사용하기 위해 On 으로 설정합니다.


RewriteLog /home/blog/rewrite_log_admin3.log

RewriteLogLevel 9

# Rewrite 실행중 Log를 남기기 위해 로그파일과 로그레벨을 지정했습니다.


RewriteRule ^/tb/([a-zA-Z0-9]+)/([0-9]+)$ /home/blog/html/blog/trackback\.php\?id=$1&post_no=$2

# 위설정은 블로그에 등록된 포스트의 트랙백 주소를 부여하기 위해 설정한 RewriteRule 로써 Pattern에 두개의 그룹이 존재하고 return URL에 순서대로 각 그룹을 $1 과 $2 로 받아 GET 변수로 치환한것입니다.


RewriteRule ^/xml/([a-zA-Z0-9]+)$ /home/blog/html/blog/rss_feed\.php\?id=$1

# 각블로그별 RSS 주소를 실제 파일로 지정한것입니다.


RewriteCond %{REQUEST_URI}     !^/admin$

RewriteRule ^/([a-zA-Z0-9]+)$ /home/blog/html/blog/main\.php?id=$1

# 먼저 RewriteCond 로 실제 존재하는 admin 이라는 디렉토리를 이어지는 RewriteRule에서 제외시키고 http://domain.com/user_id 로의 요청을 모두 /home/blog/html/blog/main.php?id=user_id로 redirect 시키는 룰입니다.


RewriteRule ^/([a-zA-Z0-9]+)/([0-9]+)$ /home/blog/html/blog/main\.php\?id=$1&post_no=$2

# /user_id/1345 로 요청하는 페이지를 /home/blog/html/blog/main.php?id=user_id&post_no=1345 로 redirect 시키는 룰입니다.



 

4. 마치면서

위에서 언급한 RewriteRule 뿐만 아니라 여러가지 상황에서 RewriteRule을 잘 활용한다면 아주 유용하게 웹페이지를 컨트롤 할수 있습니다. RewriteRule 을 세팅하기 이전에 반드시 정규표헌식에 대해 어느정도 공부한후 적용해 보실 것을 권합니다.



정규표현식이라는건 대체 뭘까요?
말 그대로 어떤 내용에 대하여 정규화된 표현식을 말합니다.
예를 들자면...

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. 정수 또는 소수

100
20.3
8.52


2. 다음의 문자열들을 만족하는 정규표현식을 만들어 보세요

aB@123_yZ
DDDD@003XXX
abcd@2_efgh