Perl Study #5

정규표현식 [2 / 2]

 

메모리로서의 괄호  :   ( )

패턴의 임의의 부분에 괄호 한 쌍을 사용할 경우 패턴에 의해 일치되는 문자열의 부분을 기억하게 함으로써 나중에 참조할 수 있게 한다.

->  /fred(.)barney1/;   # fred , 임의의 한 문자 #1, barney , #1과 동일한 한 문자

/a(.)b(.)c2d1/;   # a, 한 문자(#1), b, 한 문자(#2), c, #2와 동일, d, #1과 동일

하나 이상의 문자도 가능하다.

->  /a(.*)b1c/;       # a, 임의의 수의 문자(#1), b, #1과 동일한 수의 문자들, c

 

선택   :    |

/a|b|c/와 같이 사용시 a, b, c중 하나와 정확히 일치함을 의미한다.

->  /song|blue/;    # song과 blue 중 하나와 일치

 

앵커화 패턴

앵커는 패턴의 부분이 문자열의 특별한 부분을 확보하도록 한다.

   :  일치시킬 패턴에 대해 가리키는 부분에 단어 경계가 있을 것을 요구

->  /fred/;    # fred와는 일치하지만 frederick은 아님

/mo/;     # moe와 mole과는 일치하지만 Elmo는 아님

/+/; #  “x+y”와는 일치하지만 “++” 또는 “+”와는 아님

/abcdef/;  # 일치할 수 없음 (그 곳에 경계가 있을 수 없음)

B   :  가리키는 부분에 단어 경계가 없을 것을 요구

->  /FredB/; #  “Frederick”과는 일치하지만 “Fred Flinstone”과는 아님

^  :  문자열의 처음과 일치시키는 것이 가능한 위치에 있을 경우 문자열의 처음과 일치

->  /^a/;    # a가 문자열의 첫번째 문자일 경우 일치

/a^/;    # 두문자 a와 ^과 일치 (캐럿에 특별한 의미가 없음)

$  :  패턴을 문자열의 끝에 고정

-> /c$/;     # c가 문자열의 끝에 있을 때만 일치

 

그룹화 우선순위

이름 표기
괄호 () (?:…)
배수기 ? + * {m,n} ?? + ? * ?
연속과 앵커화 abc ^ $ A  (?=) (?!)
선택 |

->  /a|b*/;     # 하나의 a 혹은 임의의 수의 b

/(a|b)*/;    # 임의의 수의 a 혹은 b

* 우선순위를 바꾸기 위해 사용하는 괄호도 메모리에 영향을 준다. 메모리에 영향을 주지 않고 괄호를 사용하려면 (…) 형태 대신 (?:…)의 형태로 사용한다

->  /(?:Fred|Wilma) Flintstone/;    # 그룹화만 있을 뿐 아무것도 1에 저장되지 않음

 

* 정규표현식과 괄호의 영향에 대한 몇몇 다른 예

->  /abc*/ ;        # ab, abc, abcc, abccc 등과 일치

/(abc)*/;       #  “ ”, abc, abcabc, abcabcabc 등과 일치

/^x|y/;        #  행의 처음에 있는 x나 임의의 곳에 있는 y와 일치

/^(x|y)/;       #  행의 처음에 있는 x 또는 y와 일치

/a|bc|d/;      # a 혹은 bc 혹은 d

/(a|b)(c|d)/;   # ac,ad,bc 혹은 ad

/(song|blue)bird;  # songbird 혹은 bluebird

 

다른 목표의 선택  :  =~

=~의 오른쪽에 정규표현식 연산자를 받아서 그 연산자의 목표를 $_ 변수가 아닌 왼쪽의 값으로 바꾼다.

->  $a =~ “hello world”;

$a =~ /^he/;         # 참

$a =~ /(.)1/;       # 참 (두개의 l과 일치)

if ($a =~ /(.)1/){ }  # 참 그리고 무언가 실행

스칼라 문자열 값을 가져오는 어떤 표현식이라도 =~ 연산자의 목표가 될 수 있다.

->  if (<STDIN> =~ /^[yY]/){    # 입력이 y로 시작하는가?

print “And just what might that request be?” ;

<STDIN>;                # 표준입력의 행을 무시

print “Sorry, I’m unable to do that. ”;

}

 

대소문자 무시  :    / /i

대소문자를 무시하려면  /perl/i 와 같이 닫는 슬래쉬 뒤에 소문자 i를 붙인다

->  /^procedure/i;       # procedure가 행의 처음에서 대소문자 구분 없이 일치

print “any last request?”;

if (<STDIN> =~ /^y/i) {  }  # 입력이 y로 시작하는가?

 

다른 구분자의 사용

m다음에 원하는 구분자를 놓을 경우 슬래쉬 이외에도 여러가지 문자를 구분자로 사용할 수 있다.

->  /^/usr/etc/      #  표준 슬래쉬 구분자 사용

m@^/usr/etc@      #   구분자로 @을 사용

m#^/usr/etc#        #   구분자로 #을 사용

m/fred/                     #  구분자로 다시 /를 사용

 

변수 삽입의 사용

정규표현식은 다른 특별한 문자들로 사용하려고 생각하지 않았다면 변수 삽입이 된다.

->  $what = “bird”;

$sentence = “Every good bird does fly.”;

if ($sentence =~ /$what/) {     # 변수 삽입으로 bird 일치 검사

print  “The sentence contains the word $what! ”;

}

* Q , E 인용부호 이스케이프는 정규표현식 패턴일치 문자를 리터럴에 대한 일치가 되도록 도와준다

-> $what = “[box]”;

foreach (qw(in[box] out[box] white[sox])) {

if (/Q$whatE/) {   # q$whatE는 [box]가 되고 리터럴 일치를 찾음

print “$_matched! ”;

}

}

특별한 읽기 전용 변수

패턴 일치가 성공한 후에 $1, $2, $3 등은 1, 2, 3등과 동일한 값으로 사용된다

->  $_ = “this is a test”;

/(w+)W+(w+)/;    # 처음의 두 단어를 일치시킴

# $1은 “this”이고 $2는 “is”

->  $_ = “this is a test”;

($first, $second) = /(w+)W+(w+)/;    # 처음의 두 단어를 일치시킴

# $first는 “this” , $second는 “is”

* $&  :  정규 표현식이 일치된 문자열 부분

$`   :  정규 표현식이 일치되기 전 문자열 부분

$   :  정규 표현식이 일치된 후의 문자열 부분

->  $_ = “this is a sample string”;

/sa.*le/;      # 문자열 내의 “sample”과 일치

#  $`은 “this is a ”

#  $&은 “sample”

#  $’은  “string”

치환

s/  /   : 첫번째 일치에 대한 치환을 실행한다

s/  /g  : 가능한 모든 일치에 대한 치환을 실행한다

->  $_ = “foot fool buffoon”;

s/foo/bar/g;    # $_ 는 이제 “bart barl bufbarn”

* 치환 문자열에 변수 삽입이 가능하다

->   $_ = “hello, world”;

$new = “goodbye”;

s/hello/$new/;    # hello를 goodbye로 치환

패턴 문자는 고정된 문자가 아니며, 패턴이 일치되도록 한다

->  $_ = “this is a test”;

s/(w+)/<$1>/g;   #  $_ 는 이제 “<this> <is> <a> <test>” 가 됨

s/  /i  : 대소문자 구분을 하지 않는다.

* 슬래쉬가 불편할 경우 다른 구분자를 사용 가능하다. 동일한 문자를 세 번 사용하면 된다

  ->  s#fred#barney#;   # s/fred/barney/ 처럼 fred를 barney로 변환

=~ : 일치 연산자와 마찬가지로 대체목표를 명시할 수 있다

-> $which = “this is a test”;

$which =~ s/test/quiz/;        # $which는 이제 “this is a quiz”

$someplace[$here] =~ s/left/right/;    # 배열 요소를 바꿈

$d{“t”} =~ s/^/x/;     # 해쉬 요소에 “x”를 앞에 붙임

 

Split 함수

정규 표현식과 문자열을 받아 그 문자열 내에서 정규 표현식의 모든 발생을 찾는다

Split(/구분자/, 문자열) 과 같이 사용한다

->  $line = “merlyn::118:10:Randal:/home/merlyn:/usr/bin/perl”;

@fields = split(/:/,$line);    # $line을 :를 구분자로 하여 분리

# 이제 @fields 은 (“merlyn”, “”, “118”, “10”, “Randal”, “/home/merlyn”,

#                  “/usr/bin/perl”)

* 두 번째 필드처럼 공백 문자열을 만들고 싶지 않은 경우 모든 콜론을 한번에 일치시킴

->  @fields = split(/:+/,$line);

* 아무것도 쓰지 않을 경우 디폴트는 $_로 설정된다

-> $_ = “some string”;

@words = split(//);    # @words = split(//,$_); 와 동일

* $_ 를 공백문자로 구분하는 가장 간단한 방법

-> @words = split;   # @words = split(/s+/$_); 와 동일

 

join 함수

join 함수는 값의 리스트를 받아서 각 리스트 요소 사이를 접착 문자열로 이들을 서로 결합한다.

->  $bigstring = join($glue, @list); # @list 사이를 $glue로 붙여 $bigstring에 저장

* 접착 문자열을 요소들 사이 대신 요소 앞에 두고 싶을 때

->  $result = join(“+”, “”, @fields);

* 리스트 끝에 공백요소로 뒤에 붙는 접착을 할 때

->  $output = join(“ ”, @data, “”);

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다