정규표현식 [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, “”);