문자열 찾아 바꾸기

치환은 일치의 응용으로 생각하시면 됩니다. 연산자도 =~를 사용하고 문자를 둘러싸는 부호도 /입니다.
치환을 위하여 s///라는 함수를 사용합니다. 문장의 구조는
"뒤적거릴 문자열" =~ s/찾을 문자열/바꿀 문자열/옵션;
문자열을 찾아서 치환이 되었을 때 치환시킨 문자열의 수를 리턴합니다. 치환이 하나도 되지 않았다면 0을 리턴하겠죠.
# subst.pl

$_ = "Where is my baby, Oh Baby !";

if( $count = ( s/baby/lover/ ) )  # $_ =~ s/.... 로 인정됩니다.
  {  print "Replaced $count time(s).\n   \"$_\"\n";  }
else  {  print "Failed.\n";  }

print "Fore : $`\nAft  : $'\n";
위 예제의 결과를 예상해 보시고 직접 실험해 보시기 바랍니다. $count의 값만 참고로 말씀드리면 1입니다. 뒤에는 대문자로 시작하는 Baby라서 그런가 ?
아, 벌써 아셨군요. 제가 s/baby/lover/i라고 말하려 한다는 것을 !!! 한번 해 볼까요 ?
틱, 티딕, 틱틱틱 퍽 !  (퍽은 enter키 치는 소리.)
아니 ??! 결과가 이상하다 !! 왜 뒤의 Baby는 그냥 있지 ? 전종필이 가만 놔두지 않겠다 eC.... >-(

잠깐요 ! ... 아 ! 한 가지 더 있었군요. g, global substitution>, 전역 치환이라는 옵션을 사용하지 않으면 맨 처음에 발견되는 문구만 치환이 되고 그 뒤는 더 이상 뒤적거리지 않는것입니다.

해 보시죠 ..s/baby/lover/gi.. 퍽 ! ... 음, 역시 그렇지요 ?

그리고 마지막 줄의 print "Fore : $`\nAft : $'\n"의 결과도 눈여겨 보세요.

문자열의 일치에서 살펴보았던 모든 정규식(Regular Expression)이 여기서도 적용이 됩니다.

간단한 예제 하나만 해 보고 부연하지 않겠습니다.

# banana.pl

$_ = <<ENDofSTR;
Banana !
What is banananana ?
Not banananananana, but banana.
Give me a banana.
How many bananas do you want ?
A BaNaNa.
ENDofSTR

if( $count = ( s/ba(na)+/pear/gi ) ) 
  {  print "Replaced $count time(s).\n$_\n";  }
else  {  print "Failed.\n";  }

print "Fore : $`\nMid  : $&\nAft  : $'\n";
  # 새로운게 나왔죠 ?  $&
특수문자 하나 더 알려 드릴께요. $`에 앞, $'에는 뒤가 할당될 때, $&에는 마지막으로 찾은 문자열 그 자체가 할당됩니다. 물론 예제를 보시고 다 아셨겠지만요.

이제 문자단위(character, byte)의 치환(Translation)에 대해서 말씀드릴 때인 것 같군요.
문자열의 치환은 s///이지만 문자의 치환은 tr///을 사용합니다.

$string =~ tr/abc/ABC/;
위의 명령은 $string변수내의 '모든' a를 A로, b를 B로, c를 C로 바꾸어 주고 치환된 문자수를 리턴합니다. 한글은 이렇게 바꾸어지지 않는것 아시죠 ? 한글은 한 글자가 2 바이트니까요.
중요한 것 한가지는 문자의 치환에서는 문자열의 일치나, 문자열의 치환에서와는 달리 정규식(Regular Expression, RE)이 통하지 않는다는 사실입니다. 즉,
# re_tr.pl

$_ = "* is not \$";

if( $count = ( tr/*/#/ ) )
  { print "Translated $count char(s).\n$_\n"; }
else  { print "No translation.\n"; }
에서 * 부호는 부호 그 자체로 해석되는것을 알 수 있습니다.

그러나, 중요한 예외가 있습니다. 문자열의 일치와 치환에서 쓰였던 '-'부호(between)은 그대로 쓰입니다. 그래서 모든 소문자를 대문자로 바꿀 때

tr/a-z/A-Z/
를 사용할 수 있습니다.
이전 | 목록 | 다음
Comments