패턴 일치(Pattern Matching)는 문자열 내부에 어떤 특징을 가진 부분을 찾아내는 작업을 말한다. Perl에서의 패턴 일치 기능을 잘 활용하면 보다 쉽게 프로그램을 할 수 있다.

 

[형식]

/abc/

 

[형식 설명]

패턴은 슬래쉬(/) 두 개 사이에 문자를 넣어서 표현한다. /abc/ abc라는 패턴을 나타낸다.  특수 문자를 사용하여 여러 가지 다양한 조건으로 표현을 할 수 있다. 다음의 예를 살펴보자.

표현

의미

예제

xyz

같은 문자열

Xyz

x*

x가 없거나 여러 개 있다 .

“”, x, xx, xxx

x+

x가 한 개 이상 있다.

x, xx, xxx

?

0 또는 1개의 임의의 문자

“”, a, b, c

.

1개의 임의의 문자

a, b, c

^xyz

xyz로 시작한다

xyzabc

xyz$

xyz로 끝난다

abcsdxyz

[xyz]

xyz 중에 하나

x, y, z

[xyz]+

xyz 중에 하나 이상

xy, xyz, xxyz,

[a-zA-Z0-9]

모든 알파벳과 숫자 중에 하나

a, b, 4, 5,

[^xyz]

xyz가 아닌 문자

s, w, t

xy|yz|zx

xy, yz, zx 중에 하나

xy, yz, za

 

 

(1) 일치 연산자

 

[형식]

$var =~ /pattern/;

 

[형식 설명]

문자열에서 특정 패턴이 포함되어 있는지 검사하는 연산자이며 =~를 사용한다. 문자열이 패턴을 포함하고 있으면 참을 아니면 거짓을 리턴한다.

 

[예제 1]

$string = abcde;

if ($string =~ /bcd/)

{

             print Yes\n;

}

else

{

             print No\n;

}

 

 

[실행 결과]

Yes

 

[예제 설명]

앞의 예제는 일치 연산자를 사용한 간단한 프로그램이다. abcde라는 문자열이 저장된 $stringbcd라는 패턴을 포함하고 있는지 검사를 해서 포함하고 있으면 Yes, 그렇지 않으면 No를 출력한다.

 

[예제 2]

print "- Input Variable : ";

$input = <STDIN>;

chop($input);

if ($input =~ /^[\$\@][A-Za-z_][A-Za-z0-9_]*$/)

{

             print $input is correct variable.\n;

}

else

{

             print $input is invalid variable.\n;

}

 

 

[실행 결과]

- Input Variable : $abc

$abc is  correct variable.

 

- Input Variable : $32abc

$32abc is invalid variable.

 

 

[예제 설명]

앞의 예제는 Perl 변수명을 체크하는 프로그램이다. 자세히 살펴보자.

우선 Input Variable :이라는 메시지를 출력하고 사용자로부터 입력을 받는다. <STDIN>는 사용자로부터 입력을 기다리다가 입력을 하고, 엔터를 입력하면 입력된 값을 $input에 저장하고 다음으로 넘어간다. 그 다음에 다시 chop($input)이 나온다. 앞에서 이미 보아서 알고 있겠지만 chop은 문자열에서 마지막 한 글자를 제거하는 기능을 한다. 그렇다면 여기서는 왜 사용했을까? <STDIN>을 통해서 $input에 저장된 내용에는 사용자가 입력한 모든 내용이 들어간다. 예를 들어 내가 abc라고 입력하고 엔터를 쳤다고 하자. 그렇다면 $input에는 abc만 저장되는 것이 아니고 엔터(\n) 값도 저장이 되는 것이다. 그래서 실제로는 abc\n이 되는 것이다. 그렇기 때문에 엔터를 제외한 사용자가 입력한 값을 얻기 위해서는 chop을 사용하여 마지막 문자를 제거하는 것이다.

 

chop 함수는 매우 중요하다. 프로그램을 하다가 보면 chop을 하지 않아서 에러가 나거나 정확한 결과를 내지 못하는 경우가 많다. chop의 중요성을 모르고 있으면 엉뚱한 곳에서 당황하게 되는 경우가 종종 있으니 chop의 사용 방법에 대해 잘 알아두는 것이 좋다.

 

이렇게 입력된 값을 if 문에서 /^[\$\@][A-Za-z_][A-Za-z0-9_]*$/을 만족하는지 검사한다. 앞에서 소개한 패턴에 관해 잘 공부해 두었다면 위의 내용이 어떤 의미인지 금방 알 수 있겠지만 하나씩 살펴 보면 우선 ^[\$\@]은 처음이 $ @로 시작하는지를 검사하게 된다. 두 번째 [A-Za-z_]는 알파벳 대문자 A부터 Z 또는 소문자 a부터 z까지와 _ 를 포함하는지 검사한다. 그리고 마지막 부분에 [A-Za-z0-9_]*$는 모든 알파벳 또는 숫자가 없거나 1개 이상 존재하고, 알파벳 또는 숫자로 끝나는 문자열을 검사한다. 종합하면 앞에서 배워봤던 변수 이름을 짓는 규칙과 같다. 잘 기억이 나지 않으면 앞에 변수 부분을 살펴보기 바란다. 실행을 해서 $abc를 입력했더니 조건에 적합하기 때문에 correct variable이라는 메시지가 출력되었다.

 

(2) 불일치 연산자

 

[형식]

$var !~ /pattern/;

 

[형식 설명]

=~의 반대로 문자열이 패턴을 포함하고 있지 않으면 참을, 포함하고 있으면 거짓을 리턴한다.

 

(3) 치환 연산자

 

[형식]

$var =~ s/pattern1/pattern2/option;

 

[형식 설명]

문자열 $var에서 pattern1을 찾아서 pattern2로 바꾸어 주는 기능을 한다. option에 따라 기능을 조금 다르게 적용할 수 있는데 option은 다음과 같다.

 

옵션

설명

g

패턴의 모든 이벤트를 변경한다.

i

대소문자를 구분하지 않는다.

e

고체 문자열을 식으로 인식한다.

m

일치될 문자열을 다중 라인으로 취급한다.

o

단 한 번만 판별한다.

s

일치될 문자열을 단일 라인으로 취급한다.

x

패턴에서 화이트 스페이스를 무시한다.

 

다음의 예문을 살펴보자.

 

$string = I love Jane;

$string =~ s/Jane/Tony/g;

 

$string에는 I love Jane이라는 내용이 들어 있고 치환 연산자를 이용하여 Jane Tony로 바꾸는 명령이다. 수행이 끝나고 나면 $string에는 I love Tony이라는 문자열이 들어가게 된다.

 

 

(4) 변환 연산자

 

[형식]

$var =~ tr/string1/string2/option;

 

[형식 설명]

tr 연산자에서는 string1에 교체될 문자들의 목록을 포함하고, string2는 교체할 문자들을 포함한다. string1의 첫 번째 문자는 string2의 첫 번째 문자와 교체된다. string1 string2의 각각의 자리에 맞춰서 변환되는 것이다. 다음의 예문을 보자

 

$string = abcdefgabcd;

$string =~ tr/abc/def/;

 

a d, b e, c f로 변환되어 $string에는 defdefgdefd가 들어가게 된다.



(1) if ~ else 구문

 

[형식1]

if ( 조건 )

{

             조건에 따른 처리;

}

else

{

             조건에 따른 처리;

}

 

[형식2]

if ( 조건 )

{

             조건에 따른 처리;

}

elsif ( 조건 )

{

             조건에 따른 처리;

}

else

{

             조건에 따른 처리;

}

 

if ~ else 구문은 어떤 조건을 만족하는지를 검사하고 만족할 때는 if 구문 바로 아래에 있는 문장이 실행되고 만족하지 않을 때에는 else 구문을 수행한다. else 구문은 생략할 수 있으며 [형식2]에서 처럼 if ~ else를 반복해서 사용할 수도 있다. if 구문 다음에 else if를 함께 사용할 때는 elseif가 아니고 elsif인 점을 주의하기 바란다. 그리고 elsif if else 구문 사이에 있어야 한다.

 

Perl에서의 if 구문은 C if 구문과 비슷하다. 하지만 주의할 점은 Perl에서는 조건에 따른 처리 문장이 한 줄일 경우에도 { }를 사용해야 한다는 것이다.

 

[예제 6.7.1]

$a=5;

if ($a < 5)

{

             print 5보다 작다.\n;

}

else

{

             print 5보다 크거나 같다.\n;

}

[실행 결과]

5보다 크거나 같다.


앞의 예제에서 $a 5라는 값이 들어가 있고 if 문에서 $a 5보다 작은지를 검사한다. $a 5보다 작지 않기 때문에 if 구문이 수행되지 않고 else 구문이 수행되므로 5보다 크거나 같다.라는 문장이 출력된다.

 

if 문은 다음과 같이도 사용할 수 있다.

 

$a=5  if ($a < 5);

 

간단한 조건일 경우에는 위와 같은 방식으로 하면 간단하게 작성할 수 있다.


 

(2) unless 구문

 

[형식]

unless ( 조건 )

{

             조건에 따른 처리;

}

 

 

unless 구문은 if와 반대되는 말이라고 생각하면 된다. if는 어떤 조건이 참일 때 수행하는 것이지만 unless는 거짓일 때 수행된다.

 

unless (1 == 2)

{

             print Its wrong\n;

}

 

앞의 예를 보면 조건에서 1 2는 같지 않기 때문에 거짓이 된다. 거짓이면 블록 안의 내용을 수행하므로 Its wrong 이라는 결과가 출력된다.

 

if 문과 마찬가지로 unless도 다음과 같이 줄여서 사용할 수 있다.

 

$a = 1 unless $a;

 

위의 예는 $a에 값이 없을 경우에 1을 대입하라는 문장이다.

 

 

(3) while

 

[형식]

while (조건)

{

             조건에 따른 처리;

}

 while 문은 조건이 참일 경우에 블록 안의 내용을 반복해서 수행한다. 즉 조건이 참이면 블록 안의 내용을 순서대로 수행하고 다시 while 문이 있는 조건으로 돌아가서 다시 조건이 참인지 검사를 한다. 조건이 참일 경우에는 다시 불록의 내용을 수행하고 거짓이라면 수행을 중단하게 된다.

 

[예제 6.7.2]

$i=1;

$sum=0;

while ($i <= 10)

{

             $sum+=$i;

print $i : $sum\n;

}

print Sum : $sum\n;

 

 

[실행 결]

1 : 1

2 : 3

3 : 6

4 : 10

5 : 15

6 : 21

7 : 28

8 : 36

9 : 45

10 : 55

Sum : 55

 

앞의 예제는 1부터 10까지 1씩 증가하면서 값을 더하는데 각 단계별로 중간 합계를 보여주는 소스이다. while ($i <= 10)에서 $i는 처음에는 1이기 때문에 참이 되어 블록의 내용을 수행하고 다시 조건으로 돌아오면 $i 2가 되어있다. 여전히 10보다 작아서 참이 되므로 계속 반복하다가 $i 10일 때 마지막 결과를 출력하고 $i 11이 되면 조건을 만족하지 못해서 더 이상 블록의 내용을 수행하지 않고 while 문을 빠져나가게 된다.

 

 

(4) until

 

[형식]

until (조건)

{

             조건에 따른 처리;

}

 

until while과 반대로 조건을 만족할 때까지 수행하게 된다. 즉 조건이 거짓일 때 수행을 한다. if unless의 경우를 비교해 보면 이해가 쉽게 될 것이다.

 

(5) for

 

[형식]

for (초기값 설정; 끝나는 조건; 반복처리;)

{

             조건에 따른 처리;

}

 

for 문의 조건은 세 부분으로 이루어 진다. 첫 번째는 초기에 설정할 구문을 적는다. 두 번째는 for 문의 수행할 조건을 검사한다. 참일 경우에 블록의 내용을 수행하고 거짓이면 중단한다. 세 번째는 for 루프(loop)가 반복될 때마다 수행되는 구문이다. 예를 들어보자.

 

[예제 6.7.3]

$sum=0;

for ($i=1; $i <= 10; $i++)

{

             $sum+=$i;

print $i : $sum\n;

}

print Sum : $sum\n;

[실행 결]

1 : 1

2 : 3

3 : 6

4 : 10

5 : 15

6 : 21

7 : 28

8 : 36

9 : 45

10 : 55

Sum : 55

 

금방 눈치 챘을지도 모르지만 앞의 예제 결과는 while 문에서 보았던 예제와 결과가 같다. while 문을 이용한 소스를 for 문으로 바꾼 것이다. 하나씩 따라가 보자. 일단 for 문에 도착하면 $i=1;이 수행된다. 그리고 $i <= 10; 조건을 검사한다. 조건을 만족하기 때문에 블록 안으로 들어가 수행을 한다. 수행을 마치면 $i++;이 수행된다. $i 1이 증가하여 2가 되었고 다시 $i <= 10 조건을 검사한다. 여전히 만족하므로 블록의 내용이 계속 수행된다. $i 11이 되면 더 이상 조건을 만족하지 않기 때문에 블록을 수행하지 않고 밖으로 빠져나가 마지막 print 문을 실행하게 된다.

때에 따라서는 while 문을 사용하는 것 보다 for를 사용하는 것이 더 유용할 때가 있다. 개발할 때에 어느것이 적절한지 판단하여 사용하기를 바란다.

 

 

for 문을 다음과 같이 사용할 수도 있다.

 

             for ($i=1, $sum=0; $i <= 10; $i++)

 

각 조건을 입력할 때는 콤마(,)를 이용해서 여러 가지를 나열할 수도 있다. 그러나 너무 많은 조건을 나열하면 소스가 복잡하여 별로 보기 좋지 않으니 적절히 사용하는 것이 좋다.

 

(6) foreach

 

[형식]

foreach  로컬 변수(리스트)

{

             조건에 따른 처리;

}

루프를 이용하여 리스트에 저장된 요소에 대해 점검한다. foreach에 대한 수행 방법은 다음의 두 가지 예를 통해서 비교해 볼 수 있다.

 

[예제 6.7.4]

@list=(1,2,3,4,5);

 

$i=0;

$list_size=@list;

 

while ($i < $list_size)

{

print "$list[$i]\n";

$i++;

}

[예제 6.7.5]

@list=(1,2,3,4,5);

 

foreach $i (@list)

{

print "$i\n";

}

 

[실행 결]

1

2

3

4

5

 

앞의 두 가지 예제의 결과는 같다. 그런데 두 번째 예제 소스를 보면 첫 번째 예제 소스보다 훨씬 간단하다. 이런 점이 foreach의 편리함이라고 할 수 있다. 실행되는 과정을 살펴보면 우선 @list에는 1부터 5까지의 5개의 숫자가 들어있다. foreach $i (@list) @list에서 각 요소의 값을 하나씩 꺼내서 $i에 저장한 다음에 블록 안의 내용을 수행하는 것이다. 수행은 @list의 모든 요소를 하나씩 다 꺼내서 사용하게 되므로 @list의 크기 만큼 수행하는 것이다.

여기서 $i는 로컬 변수로 foreach 문이 수행되는 동안에만 유효한 변수이다. foreach 문 이전에 $i를 사용하고 있었더라도 foreach 문 수행 후에 기존의 $I 값은 영향을 미치지 않는다.

 


(7) do

 

[형식]

do {

             조건에 따른 처리;

} while (조건)

또는

 

} until (조건)

 

지금까지 나왔던 루프 프로그램에서는 루프를 실행하기 전에 조건식을 먼저 판별하였다. 그러나 do 문을 사용하게 되면 일단 블록 안의 내용을 먼저 실행하고 조건을 판별하게 된다.

 

[예제 6.7.6]

$i=1;

do {

print $i\n;

$i++;

} while ($i <= 10);

 

[실행 ]

1

2

3

4

5

6

7

8

9

10

일단 처음에는 아무런 조건 없이 블록의 내용을 수행한다. $i는 처음에 1이었다가 한 번 수행이 되고 2가 되었다. 수행이 완료되면 while 문에서 $i <= 10 조건을 만나서 만족하는지 여부를 판단한다. 조건을 만족하므로 다시 블록의 내용의 수행을 반복하다가 $i 11이 되면 수행이 끝나고 while 문에서 조건을 만족하지 못하므로 수행을 중단한다.


 

(8) last

 

[형식]

last;

 

일반적으로 루프를 빠져 나오려면 처음이나 끝부분에 있는 조건문으로 판별하여 만족하지 못할 때 루프를 빠져 나오게 된다. 그러나 필요에 따라서 루프 수행 도중에 빠져 나와야 할 상황이 있을 수 있다. 이럴 때는 last 명령을 사용한다. 루프 안에서 last 명령을 사용하면 더 이상 조건을 비교하지 않고 강제로 루프를 빠져 나오게 된다.

 

[예제 6.7.7]

for ($i=1, $sum=0; $i <= 10; $i++)

{

             $sum+=$i;

             if ($sum > 20)

             {

                           print Current Sum : $sum\n;

                           last;

             }

}

 

[실행 결]

Current Sum : 21

 

앞의 예제를 살펴보면 1부터 10까지의 합계를 구하는 도중에 합계가 20이 넘어가면 중단을 하고 합계를 출력하는 프로그램이다. 루프 안의 조건에서 $sum > 20을 만족하는 시점에 결과를 출력하고 last 명령으로 루프를 종료했다. last 명령을 만나면 더 이상 조건을 판별하거나 블록 안의 내용을 수행하지 않게 되고 무조건 루프 밖으로 빠져 나가게 된다.

 


(9) next

 

[형식]

next;

 

last는 루프의 실행을 중지시키는 명령이다. 그러나 next를 사용하면 실행중인 루프를 중단하고 다음 루프로 건너 뛸 수 있다.

 

[예제 6.7.8]

for ($i=1; $i <= 10; $i++)

{

             if ($i % 2 == 1)                  # 홀수일 때

             {

                           next;

             }

             print $i\n;

}

[실행 결과]

2

4

6

8

10

 

앞의 예는 1부터 10까지의 정수 중에서 짝수만 출력하는 프로그램이다. for 문에서는 1부터 10까지 10번의 루프를 돌게 되어 있고, 그 값을 출력하게 되어 있다. 루프에 들어가면 if 문에서 $i를 나머지 연산자 %를 사용하여 2로 나누어 본다. 2로 나누어서 나머지가 1이면 홀수이기 때문에 next 문을 사용해서 숫자를 출력하지 않고 다음 루프로 넘어가게 된다. next 문은 주로 루프에서 예외 사항 같은 경우에 적용할 수 있다.

 

 


(1)
산술 연산자

 

기본적으로 +, -, *, /의 사칙 연산자를 지원하고 누승 연산자(**), 나머지 연산자(%), 단항 부정 연산자 등이 있다.

 

$result1 = 4 ** 3;

$result2 = 26 % 3;

-$y;

 

누승 연산자는 첫 번째 줄에서와 같이 $result1에는 4 3번 곱한다는 뜻이다. 64가 된다.

나머지 연산자는 두 번째 줄에서와 같이 $result2에는 26 3으로 나누고 난 나머지 값이 저장되며 값은 2가 된다.

단항 부정 연산자는 숫자나 변수 앞에 을 붙여서 사용한다. 이 의미는 해당 값에 1을 곱한 것과 같다.

 

(2) 비교 연산자

 

Perl은 문자열 비교 연산자와 수치 비교 연산자가 다르다. 다음의 내용은 수치 비교 연산자와 문자열 비교 연산자를 정리한 것이다.

 

연산

문자열 연산자

수치 연산자

보다 작다

lt

< 

보다 크다

gt

> 

같다

eq

=

보다 작거나 같다

le

<=

보다 크거나 같다

ge

>=

같이 않다

ne

!=

비교 후 1,0,-1을 반환

cmp

<=>

 

Perl에서는 변수에 문자열과 숫자를 구분하지 않고 저장되기 때문에 비교 연산자를 사용할 때는 정확히 사용해야 한다. 다음의 예를 살펴보자.

 

$num1=123;

$num2=45;

$result1=$num1 < $num2;

$result2=$num1 lt $num2;

 

앞의 예에서 $num1 $num2에는 각각 123 45라는 값이 저장되어 있다. 여기서 $result1에서는 <을 사용하여 수치 비교를 했고, $result2에서는 lt를 사용하여 문자열 비교를 했다. $result1 123 < 45가 되기 때문에 참이 된다. 그러나 $result2에서는 123 lt 45가 되므로 거짓이 된다. 문자열에서는 12345 보다 작기 때문이다. 참고로 문자열의 비교는 각 자리 별로 아스키 코드를 기준으로 비교를 한다. 같은 값을 가지고 비교를 했지만 다른 연산자에 따라 다르게 결과가 나오기 때문에 문자열과 숫자 비교는 정확히 사용해야 한다.

 

(3) 대입 연산자

 

기본적인 대입 연산자는 = 이다. $a = $b의 형식으로 왼쪽의 값을 오른쪽에 대입하는 것이다. 그러나 다음과 같은 다양한 연산자를 활용하면 다양한 연산을 할 수 있다.

 

연산자

수행결과

$a = 5

$a 5를 대입

$a += 5

$a의 값에 5를 더해서 $a에 대입

$a -= 5

$a의 값에서 5를 빼서 $a에 대입

$a *= 5

$a의 값에 5를 곱해서 $a에 대입

$a /= 5

$a의 값을 5로 나눠서 $a에 대입

$a %=5

$a의 값을 5로 나눈 나머지를 $a에 대입

$a **= 5

$a의 값을 5번 곱해서 $a에 대입

$a .= end

$a의 문자열에 end라는 문자열을 붙여서 $a에 대입

 

(4) 논리 연산자

 

논리 연산자는 어떤 조건이 참인지 거짓인지 판별할 때 사용한다. AND 연산자 &&는 각 조건을 모두 만족할 때 참이 되고 OR 연산자 ||는 어느 한 조건만 만족하면 참이 된다.

 

$a=1;

$b=2;

$result1 = ($a > 0) && ($b < 2);

$result2 = ($a > 1) || ($b < 3);

 

앞의 예를 보면 $result1에서는 $a > 0이 참이고 $b < 2가 거짓이므로 결과는 거짓이 된다. $result2에서는 $a > 1이 거짓이지만 $b < 3이 참이기 때문에 결과는 참이 된다.

 

 

(5) 자동 증가와 자동 감소 연산자

 

$num = $num + 1;

$num += 1;

 

앞의 예는 변수에 1을 더하는 방법이다. 여기에는 다음과 같은 방법이 또 있다.

 

$num++;

++$num;

 

이 방법은 모두 $num 1을 더하는 연산이다. 차이점은 $num++이 어떤 문장 속에서 사용 되었을 때 해당 라인이 수행되고 나서 값이 증가하는 반면 ++$num은 값이 증가한 후에 라인이 수행된다. 자세한 예로 다음을 살펴보자.

 

$num1=5;

$num2=5;

$result1 = $num1++;                       # $result1=5   $num1=6

$result2 = ++$num2;                       # $result2=6   $num2=6

 

$num1 $num2에는 5라는 값이 들어있다. 그리고 $result1에는 $num1의 값이 대입되고 나서 $num1 1 증가 시키게 된다. 그래서 $result1에는 5가 들어가고 $num1 6이 된다. 그러나 $result2에서는 $num2의 값이 먼저 1 증가하고 나서 $result2에 값이 저장되므로 $result2 6이 되고 $num2 6이 된다.

 

자동 감소 연산자는 ++ 대신 --을 사용한 것이고 사용하는 방식은 같다.

 

 

(6) 문자열 연결과 반복 연산자

 

문자열 연결 연산자는 두개의 문자열을 하나로 합치는 것이다. .을 사용하며 다음의 예를 살펴보자.

 

$string = Perl . Book;

 

앞에서 Perl이라는 문자열과 Book이라는 문자열을 그대로 붙여서 $string에는 PerlBook 이라는 값이 저장된다. 변수를 사용해도 같은 값을 얻는다.

 

$string1 = Perl;

$string2 = Book;

$string = $string1 . $string2;

 

앞의 경우도 결과는 마찬가지로 PerlBook 이 된다. 이 때 . 연산을 해도 $string1 $string2에는 아무런 영향이 없다.

 

문자열 반복은 문자열을 여러 번 반복한 다음에 이들을 합치며 x 를 사용한다.

 

$string = a x 5;

 

앞의 문장은 a 5번 반복해서 하나로 합친 결과를 $string에 저장하게 되므로 aaaaa  저장된다. 이 연산에서도 마찬가지로 변수를 지정해서 사용할 수 있다.

 


문자열 반복 연산자를 사용할 때는 연산자 양쪽에 있는 변수나 값 사이에 공백을 주어야 한다. 연산자인 x가 문자이기 때문에 공백이 없을 경우에는 변수와 붙어서 다른 변수로 인식할 수도 있기 때문이다. 다음의 예를 살펴보자.

 

$string = $text x 5;            # 맞다

$stinrg = $textx 5;             # 틀리다

$string = $text x5;             # 틀리다

 

두 번째 줄에는 $text x가 붙어서 $textx라는 변수인 것처럼 보인다. 이럴 경우 에러가 발생하게 된다.


 기본적인 웹의 형태는 서버에 있는 HTML과 이미지 등을 클라이언트쪽으로 전달해 주는 일방적인 방식이다. 이런 일방적인 방식에서 좀더 발전해서 서버와 클라이언트에서 서로 주고 받는 양방향의 서비스를 가능하게 하는 것이 CGI이다.

CGI(Common Gateway Interface)란 간단하게 말하면 서버에서 작동하는 프로그램이라고 말할 수 있다. 서버에서 어떤 기능을 수행한 뒤에 결과를 일정한 형태로(, HTML) 클라이언트쪽으로 넘겨주면 클라이언트의 브라우저에서 이 결과를 보여주게 된다.

사용자 삽입 이미지

<그림> CGI 작동 방식 개요



위의그림은 CGI의 작동 방식을 간략하게 나타내고 있다. 클라이언트(사용자)가 사이트에 접속하여 어떤 값을 넘겨주었을 때 웹 서버는 이 값을 받아서 해당 프로그램을 실행시킨다. 프로그램이 수행된 결과가 웹 서버쪽으로 넘어가고, 이 결과를 클라이언트의 화면에 나타나게 된다.  CGI는 웹 프로그램의 기본 개념으로 보면 된다.

 

 

 지금까지 알아본 배열 변수는 저장된 리스트의 값을 찾기 위해서는 첨자를 사용하였다. 예를 들어 $array[3]은 배열 변수 @array에 저장된 4번째 값을 나타낸다. 그러나 배열 변수는 한 가지 문제가 있다. 배열의 특정 요소에 어떤 값이 저장되어 있는지 프로그램을 작성하는 사람이 모두 기억하기가 어렵다는 것이다.

 예를 들어 다음의 예를 보자. @student라는 학생 정보를 담고 있는 배열이 있다고 하자.

 

$student[0]= 길동;                  # 이름

$student[1]= 123456;                 # 학번

$student[2]= 서울시;                  # 주소

$student[3]= 345-6789; # 전화

 

위와 같이 0번부터 순서대로 이름, 학번, 주소, 전화를 대입시켰다. 이정도로 간단하다면 별로 문제가 되지 않을 것이다. 그러나 배열 내용이 많을 수록 어떤 번호에 어떤 항목이 들어가는지 기억하기가 어려울 것이다.

배열 변수가 이런 문제점을 가지고 있는 것은 배열의 값을 참조하기 위해 숫자로 된 첨자를 사용하기 때문이다. Perl에서는 이러한 문제를 극복하기 위해 또 다른 종류의 배열을 지원한다. 이것이 조합 배열(Associative array)이다. 조합 배열은 숫자뿐만 아니라 임의의 스칼라 값도 첨자로 사용한다.

일반 배열 변수와 조합 배열 변수를 구분하기 위해서 일반 배열에서 사용하는 @ 문자 대신에 % 문자를 사용하다. 그 뒤에 변수명은 일반 변수명의 규칙과 동일하다.

 

 

%students=(name, 홍길동, id, 123456, address, 서울시, phone, 345-6789);

$name=$students{name};                         # 홍길동

$id=$students{id};                                    # 123456

$address=$students{address};               # 서울시

$phone=$students{phone};                      # 345-6789

 

앞에서 %students라는 조합 배열에 값을 대입할 때는 배열 첨자와 값을 번갈아 가면서 쓰면 된다. 즉 첨자가 name 인 배열의 값은 홍길동이 되고 id인 배열의 값은 123456이 되는 것이다.  Perl5에서는 조합 배열에 대입할 때 아래와 같이 좀더 보기 쉽게 => 를 사용해서 대입할 수 있다.

 

%students=(name=>홍길동, id=>123456, address=>서울시, phone=>345-6789);

 

다음과 같이 배열 내용을 추가할 수 있다.

$students{mobile}=234-5678;

 

그렇다면 배열 요소를 삭제할 수 있을까? 물론 있다. 삭제는 delete라는 함수를 사용한다.

delete($student{mobile});

 

위와 같이 실행하면 배열 %students에서 mobile을 첨자로 하는 요소를 삭제하게 된다.

 

배열의 대입에 관하여 알아보자. 앞에서 @array2=@array와 같은 예를 보았다. 이런 경우는 같은 배열이 만들어지게 된다. 그러나 다음의 예를 살펴보자.

 

@students=(name, 홍길동, id, 123456, address, 서울시);

%students=@students;

 

앞의 문장은 어떻게 처리될까? 결과는 @students의 내용이 %students 조합 배열에 그대로 저장된다. 다른점이라면 첨자와 값의 순서로 조합 배열의 형태로 저장된다는 점이다. $students[0]name $students[1]홍길동, $students[2]id와 같았지만 대입을 하고 나면 $students{name}홍길동, $students{id}123456과 같이 저장되는 것이다. 잘 이해가 되지 않는다면 예제를 작성해서 실행해 보기 바란다. 값을 이것 저것 바꿔서 실행해 보면 이해가 될 것이다.

 

참고로 @students %students는 완전히 다른 배열 변수이다. 이름이 같아도 일반 배열과 조합 배열이기 때문에 다르게 인식된다.

 

다음의 경우는 일반 배열에서와 같이 같은 조합 배열이기 때문에 %students의 내용이 그대로 %students2에 대입된다.

 

%students2 = %students;

 

배열을 삭제할 때는 delete 함수를 사용한다.

 

 

배열에서 모든 요소를 출력하고 싶을 때 일반 배열은 0부터 순서대로 첨자가 부여되기 때문에 배열의 크기를 측정한 다음에 0부터 순서대로 값을 출력하면 되지만 조합 배열에서는 첨자의 값이 임의의 숫자 또는 문자로 이루어지기 때문에 어떤 첨자를 가지고 있는지 알 수가 없다.  이럴 때는 keys라는 함수를 이용한다. keys(%array)라고 하면 첨자의 목록을 배열로 리턴한다.

다음의 예는 조합 배열의 모든 값을 출력하는 예제이다.

 

foreach $key (sort keys(%students))

{

             print $key : $students{$key}\n;

}

 

앞의 예제는 %students의 모든 내용을 첨자와 함께 값을 출력하는 것이다.

조합 배열의 저장 순서는 항상 임의적이다. 저장되는 순서대로 출력된다는 보장이 없다. 그렇기 때문에 앞에서 배웠던 sort 함수를 사용해서 정렬을 해준 것이다.

 

 

리스트는 괄호로 묶여진 일련의 스칼라 값들이다. 다음의 예를 보자.

(5, book, 4, perl)

위의 리스트에는 4개의 요소로 구성되어 있다. 리스트의 길이에는 제한이 없다. 그리고 어떤 스칼라 값도 포함할 수 있다.

특정 목적으로 만들어진 변수에 리스트를 저장한 변수를 배열 변수(Array Variable)이라고 하고 줄여서 배열이라고 한다.

 

 

@numbers=(1,2,3,4,5);

@colors=(Red,Green,Blue);

@array=(5,perl,computer,45);

 

배열은 @로 시작하는 변수이다. 배열의 값을 사용할 때는 $numbers[1]과 같이 $를 사용하고 [ ]를 사용하여 배열 번호를 입력하면 된다. 번호는 0번부터 시작한다. 앞에서 $numbers[3]의 값이 0번부터 시작하면 처음부터 4번째의 값인 4가 된다.

그렇다면 $numbers[5]의 값은 무엇일까? @numebrs 0번부터 4번까지 5가지가 있다. $number[5] @numbers 배열의 6번째 값을 의미하는데 실제로 존재하지 않는 값이다. 이럴 경우에는 0(null)이 된다.

 

배열에도 스칼라 변수에서와 마찬가지로 숫자와 문자열 값을 구분하지 않는다. @array에서와 같이 배열에 값을 넣을 때도 마찬가지로 숫자값과 문자값을 혼용하여 입력할 수 있다.

 

@array2 = @array;

 

위의 식에서는 @array의 내용이 @array2에 그대로 대입된다. 같은 배열이 되는 것이다.

그렇다면 다음과 같은 경우는 어떻게 될까?

 

$size=@array;

 

눈치가 빠른 사람이면 변수 이름을 보고 알았을 것이다.  $size에는 @array 배열의 크기가 대입된다. @array에는 모두 네 가지의 값이 저장되어 있으므로 4라는 값이 대입된다.

 

다음의 예는 배열의 마지막 첨자(subscript)를 대입하는 것이다. $last_index에는 2가 대입된다.

 

$last_index=$#colors;

 

리스트에는 몇 가지 함수가 있다. 하나씩 알아보자.

 

(1) shift

- 리스트의 첫 요소를 꺼낸다.

 

@list=(1,2,3,4);

$num = shift (@list);

 

결과는 $num에는 1이 들어가고 @list=(2,3,4)가 된다. 리스트 배열에서 첫 번째 요소를 꺼내고 해당 내용을 삭제한다.

 

(2)unshift

- 리스트의 처음에 요소를 추가하고 각 요소는 뒤로 하나씩 밀리게 된다.

 

@list=(1,2,3,4);

unshift(@list, 0);

 

결과는 @list=(0,1,2,3,4)가 된다. 지정된 값이 리스트의 첫 번째 요소가 되고 나머지는 그 뒤를 이어 하나씩 밀리게 되는 것이다.

 

(3) push

- 리스트의 마지막에 요소를 추가한다.

 

@list=(1,2,3,4);

push(@list, 5);

 

결과는 5 @list의 마지막에 추가가 되어 @list=(1,2,3,4,5)가 된다.

 

(4) pop

- 리스트의 마지막 요소를 꺼낸다.

 

@list=(1,2,3,4);

$num=pop(@list);

 

결과는 @list의 마지막 요소 4를 꺼내서 $num에 대입하게 되고 @list=(1,2,3)이 된다.

 

(5) sort

- 리스트를 순서대로 정렬한다.

 

@list=(3,2,5,4,1);

@list=sort(@list);

 

결과는 @list에 있던 (3,2,5,4,1)을 값을 크기 순대로 정렬하여 (1,2,3,4,5)의 값이 @list에 다시 저장된다.

 

(6) reverse

- 리스트의 순서를 역순으로 뒤집는다.

 

@list=(1,2,3,4,5);

@list=reverse(@list);

 

결과는 @list (1,2,3,4,5)를 거꾸로 정렬하여 (5,4,3,2,1) @list에 저장된다.

 

 

1

2

3

4

$string1=변수입니다;

$string2=변수입니다;

$number1=100;

$number2=100;

 

그냥 일반적인 변수를 스칼라 변수(Scalar Variable)이라고 하고 $로 시작한다. $ 다음에 변수 이름을 쓰면 된다. 변수 이름은 첫 글자는 알파벳 또는 밑줄(_) 이고 다음에는 알파벳, 숫자, 밑줄 이어야 한다.

변수에 문자열을 대입을 할 때는 1라인 또는 2라인과 같이 따옴표를 사용하는데 차이점은 는 따옴표 안에 다른 변수가 있을 경우에 해당 값이 치환이 되서 저장되지만 의 경우에는 변수 이름이 그대로 저장이 된다. 는 내용이 써있는 그대로 반영된다는 것이다.

Perl C에서처럼 변수의 타입을 지정해 주지 않아도 된다. 숫자를 넣어도 되고 문자를 넣어도 된다. 앞의 형식에서 3라인은 숫자 100을 저장한 것이고 4라인은 문자열 100을 저장한 것이다. 그러나 Perl에서는 상관이 없다. 문자 형식으로 대입을 했더라도 4라인은 특별한 변환 함수를 사용하지 않아도 숫자로 사용될 수 있다. 다음의 예를 실행해 보자.

 

 

1

2

3

4

5

6

7

8

9

10

$value1=100;

$value2=50;

$sum1 = $value1 + $value2;

$sum2 = $value1 . $value2;

$sum3 = $value1 + $value2;

$sum4 = $value1 + $value2;

print Sum1 : $sum1\n;

print Sum2 : $sum2\n;

print Sum3 : $sum3\n;

print Sum4 : $sum4\n;

 

위의 예제를 실행하면 다음과 같은 결과가 나온다.

 

[실행 결과]

Sum1 : 150

Sum2 : 10050

Sum3 : 100 + 50

Sum4 : $value1 + $value2

 

$value1에서 를 사용하여 100이라는 값을 저장하고 $value2에서는 50을 숫자로 저장을 했지만, $sum1에서는 숫자로 연산이 되고 $sum2에서는 문자로 연산이 된 것을 볼 수 있다. 4라인에서 .은 문자열을 붙이라는 명령이다. 이처럼 Perl은 변수 타입에 신경 쓰지 않아도 된다. 데이터 타입을 엄격히 선언하고 사용하는 언어를 사용했던 사람은 상당히 편하게 느낄 것이다. 하지만 프로그램이 복잡해지면 원하지 않은 결과를 얻을 수도 있으니 주의해야 한다.

실행 결과에서 Sum3 Sum4는 앞에서 말한 의 차이점을 보여주고 있다. Sum3 $value1 $value2의 값이 치환되어서 출력되었고, Sum4 $value1 $value2를 문자열로 출력하였다. 예를 보면 의 차이점을 알 수 있을 것이다.

 

앞의 예제에 보면 print 명령의 마지막에 \n 라는 것을 볼 수 있다. 이것은 이스케이프 시퀀스(Escape Sequence)라고 하는데 문자열 안에서 어떤 특정한 기능을 수행하며 이스케이프 시퀀스는 백슬래시() 뒤에 문자로 이루어져 있다. 한글을 지원하는 에디터에서는 대부분이 \과 같이 원화 표시로 나오게 되는데 어떻게 사용하던지 상관은 없다. 주의할 점은 조금 전에 알아보았지만 이스케이프 문자는 이중 따옴표(“”)에서만 작동한다는 점입니다.

다음은 이스케이프 문자의 예이다.

 

Escape 문자

기능

\a

(Beep)

\b

백스페이스(Backspace)

\cn

Ctrl + n 문자

\f

폼 피드(Form feed)

\l

다음 글자를 소문자로

\L

다음의 모든 글자를 소문자로

\n

줄바꿈(Newline)

\r

캐리지 리턴(Carriage return)

\Q

특수 패턴 문자 무시

\t

(Tab)

\u

다음 글자를 대문자로

\U

다음의 모든 문자를 대문자로

\v

버티컬 탭(Vertical tab)

 

백슬래시는 이중 따옴표 안에서 $ , @, 등의 문자를 표시할 때도 사용한다.

 

print Variable name is $name;

 

앞의 경우는 변수 이름을 표시하려고 하지만 변수 $name의 값이 대입되어 결과가 출력될 것이다. $name이라는 변수에 1이라는 값이 들어있다면 결과는 Variable name is 1 이 될 것이다. 그러나 다음과 같이 하면 변수 이름이 출력된다.

 

print Variable name is \$name;

 

위의 경우에는 백슬래시 다음에 오는 문자는 그대로 출력되며 결과는 Variable name is $name이 된다.

 

 

 다음의 소스를 에디터에 입력한 후에 hello.pl이라고 저장해 보자.

 

1

2

3

#!/usr/bin/perl

print "Hello World. This is Perl\n";

exit;

 

앞에서 작성한 hello.pl을 실행해 보자. 실행은 두 가지 방법으로 할 수 있다.

(1) Perl 인터프리터(Interpreter)와 함께 실행
 
형식)

 perl hello.pl

 

(2) 소스 파일을 실행
 
형식)

 hello.pl

 

(1)번의 방식은 윈도우나 유닉스 계열에서 모두 사용이 가능하다. 이 경우에는 물론 Perl 인터프리터가 PATH에 설정되어 있어서 아무 디렉터리에서나 실행이 가능해야 한다. 그렇지 않으면 전체 경로를 입력해서 실행해야 한다.

 

(2)번 방식은 주로 유닉스 계열에서 실행하는 방식으로 소스 파일 첫째 줄에 Perl 인터프리터의 위치를 미리 지정해 놓는다. 앞의 소스에서는 #!/usr/bin/perl Perl 인터프리터의 경로를 나타내준다. 시스템에 따라 경로가 다르므로 perl 경로를 알아본 다음에 넣어야 한다. 대체로 리눅스는 /usr/bin/perl 이고 유닉스에서는 /usr/local/bin/perl에 있다. perl 인터프리터의 경로를 알기 위해서는 아래와 같이 which 명령을 사용면 경로를 알 수 있다.

 

prompt> which perl

/usr/bin/perl

 

프롬프트에서 위와 같이 which perl 이라고 입력하면 경로를 출력해 준다. 만약에 설치가 되어 있는데 경로가 출력되지 않는다면 perl 파일이 있는 폴더가 PATH에 설정되어 있지 않기 때문이다. 환경설정에 /usr/bin 이나 /usr/local/bin 등의 perl 파일이 있는 경로를 PATH에 추가해 주면 된다.

 

한 가지 주의할 점은 유닉스 계열에서는 파일명을 입력해서 실행하려면 파일에 실행 권한이 있어야 한다. 일반적으로 생성되거나 FTP로 전송한 파일은 실행 권한이 없기 때문에 다음과 같은 명령을 먼저 입력해야 한다.

 

$chmod +x hello.pl

위의 명령은 매번 실행할 때 마다 입력하는 것이 아니고 처음 한 번만 입력하면 된다. 해당 파일을 삭제하지만 않는 다면 실행 권한이 유지된다.

 

[알아두기 시작]

인터프리터(Interpreter)해석자, 통역자 라는 의미이다. 여기서 Perl 인터프리터라는 것은 Perl의 소스를 해석하고 결과를 나타내주는 프로그램을 말하는 것이다. C와 같이 컴파일된 후 실행되는 언어와 달리 Perl은 실행할 때 소스가 해석되기 때문에 Perl 인터프리터의 위치를 지정해 줘야 한다.

[알아두기 끝]

 

실행한 결과가 다음과 같이 나온다면 정상적으로 실행된 것이다.

> hello.pl

Hello World. This is Perl

> 

 

소스를 살펴보자. 우선 1라인은 앞에서 설명한 대로 Perl 인터프리터의 경로이다. #은 원래 주석을 의미하며 첫 번째 줄은 Perl 인터프리터의 경로를 의미한다. 2라인은 print 명령으로 따옴표 안의 내용을 그대로 출력한다. 3라인은 종료하는 명령이다. 각 라인은 ; 으로 종료한다. 1라인은 실제로 수행되는 줄이 아니기 때문에 ; 를 사용하지 않는다.

아주 간단한 예제로 어떤 형식으로 작성하고 작동되는지 알아보았다.

이제부터는 변수를 시작으로 Perl에 대해서 좀더 자세히 알아보자.

CGI(Common Gateway Interface)라는 개념이 생기고 나서 Perl CGI라고 생각할 정도로 CGI로서의 Perl은 상당한 인기를 누렸다. 그러나 Perl CGI 이외에도 다양한 방법으로 활용할 수 있다. 앞으로 여러 회에 걸쳐 Perl의 기초에 대해 알아보고 활용하는 방법에 대해서도 알아보자.


Perl은 리눅스와 밀접한 관계를 가지고 있다. 스크립트 언어의 장점을 살려 시스템 관리를 할 수도 있고 웹 프로그래밍(CGI)에도 사용할 수 있다. 요즘은 ASP, PHP 등의 웹 전용 프로그래밍 언어들이 등장하면서 인기가 조금 시들해 지기도 했지만 여전히 Perl 은 강력한 언어라고 할 수 있다. 예를 들어 웬만한 해킹 스크립트 들이 Perl로 작성되어 있기도 하다.

이번 회에는 Perl 언어에 대한 기본적인 지식과 필요한 프로그램을 설치하는 방법에 대해 알아보도록 하자.



1. Perl 이란?

 

Perl Practical Extraction and Report Language의 약자로 레리 월(Larry Wall)이 유닉스 환경에서의 프로그램 코딩용 언어로 개발한 것으로 지속적으로 업데이트를 거쳐 2001년 봄 현재 5.6버전이 릴리즈(Release) 되어 있다.

Perl의 특징을 살펴보면 다음과 같다.

 

- Perl C, awk, sed, sh과 같은 언어들의 장점을 가지고 있다.

- Perl은 쉘 스크립트(Shell Script) 언어로 컴파일러(Compiler)가 필요 없다.

- Perl은 문자열 처리가 어떤 언어보다도 뛰어나다.

- Perl은 시스템 프로그래밍에 유용하다.

- Perl은 여러 운영체제를 지원한다.

 

Perl의 장점을 간략하게 알아보았다. 전에 C 등의 다른 언어를 다루어본 경험이 있는 사람이라면 Perl을 쉽게 배울 수 있을 것이다. C와 많은 부분이 유사하고 프로그램을 작성하기가 보다 편리하기 때문에 다른 언어를 배울 때 보다 쉽게 익힐 수 있을 것이다.

이제부터 Perl의 기초부터 차근차근 배워보자.

 

 

[알아두기 시작]

인터프리터(Interpreter)해석자, 통역자 라는 의미이다. 여기서 Perl 인터프리터라는 것은 Perl의 소스를 해석하고 결과를 나타내주는 프로그램을 말하는 것이다. C와 같이 컴파일된 후 실행되는 언어와 달리 Perl은 실행할 때 소스가 해석되기 때문에 Perl 인터프리터의 위치를 지정해 줘야 한다.

[알아두기 끝]

 

실행한 결과가 다음과 같이 나온다면 정상적으로 실행된 것이다.

> hello.pl

Hello World. This is Perl

> 

 

소스를 살펴보자. 우선 1라인은 앞에서 설명한 대로 Perl 인터프리터의 경로이다. #은 원래 주석을 의미하며 첫 번째 줄은 Perl 인터프리터의 경로를 의미한다. 2라인은 print 명령으로 따옴표 안의 내용을 그대로 출력한다. 3라인은 종료하는 명령이다. 각 라인은 ; 으로 종료한다. 1라인은 실제로 수행되는 줄이 아니기 때문에 ; 를 사용하지 않는다.

아주 간단한 예제로 어떤 형식으로 작성하고 작동되는지 알아보았다.

이제부터는 변수를 시작으로 Perl에 대해서 좀더 자세히 알아보자.


+ Recent posts