전종필
정규식을 사용할 때, 임의의 내용을 적용할 경우가 종종 있습니다. 특히 이 정규식이 for, foreach, while 등의 루프 안에서 사용될
경우가 이 팁의 논의 대상입니다.
정규식 안에서 변수를 사용할 경우, 프로그램은 루프를 돌 때 마다 이 변수의 값을 질의하여 대치한 후
사용해야 합니다.
# 변수 $input을 정규식에 적용한다고 합시다.
while($line=<FILE>) {
if( $line =~ /$input/ ) {
push @found, $line;
}
}
위와 같은 경우 $input은 while 루프내에서 한 번도 변하지 않을 것입니다. 그런데, 매번
$input의 값을 질의하여 사용한다면 손해라는 느낌이 들 것입니다.
이럴때 정규식에 /$input/
o와 같이
o
옵션을 사용합니다.
while($line=<FILE>) {
if( $line =~ /$input/o ) {
push @found, $line;
}
}
이와 같이 하면 Perl은 이 값을 루프의 처음 한 번만 질의하고, 그 다음에는 그 값을 계속해서
사용합니다. 하지만 $input의 값이 루프 내에서 한번이라도 변한다면 이 옵션을 사용하면 안되겠지요.
이 옵션은 s///에서도 마찬가지로
사용할 수 있습니다.
$keys = join( '|', @ARGV );
while($line=<FILE>) {
if( $line =~ s/^($keys)=(.+)/$1="$2"/o ) {
push @lines, $line;
}
}
정말 그런지 의심스러우시다면 다음 코드를 직접 실행시켜 보시기 바랍니다.
@arr = qw( aaa bbb ccc );
@data = qw( aaa=1 xxx=4 bbb=55 ccc=87 rrr=87 );
my $keys = join( '|', @arr);
print "$keys\n";
foreach my $d ( @data ) {
if( $d =~ s/^($keys)=(.+)/$1="$2"/o ) { # xxx=4 부터 $keys는 HELLO이지만 o 옵션때문에 괜찮습니다.
push @lines, $d;
}
$keys = "HELLO"; # 여기 일부러 변화를 !!!
}
print "$keys\n";
print join("\n",@lines,'');
출력되는 내용은
aaa|bbb|ccc
HELLO
aaa="1"
bbb="55"
ccc="87"
입니다. 루프가 아닌 경우라도 같은 패턴을 여러번 사용한다면 역시 마찬가지로 적용할 수 있습니다.