[ 다른 데이터 변환 ]
서브 문자열 찾기
index() 는 찾는 문자열의 위치를 알아내어 그 첫 문자의 정수로 된 인덱스를 리턴한다. 인덱스는 0으로 시작하여 한문자당 1씩 늘어난다. 찾을 수 없을 때는 –1을 리턴한다
-> $x = index($string, $substring); # $string에서 $substring의 위치를 찾아 $x에 리턴
-> $where = index(“hello”, “e”); # $where는 1
$person = “barney”;
$where = index(“fred barney”, $person); # $where는 5
@rockers = (“fred”, “barney”);
$where = index(join(“ ”, rockers), $person); # 동일
l 찾는 문자열, 찾을 문자열 모두는 리터럴 문자열, 문자열을 담은 스칼라 변수, 문자열 값을
값는 표현식까지도 가능하다
-> $which = index(“a very long string”, “ong”); # $which는 7
$which = index(“a very long string”, “lame”); # $which는 –1
l 한 군데 이상의 문자열이 서브 문자열을 가질 경우, index는 가장 왼쪽의 위치를 리턴한다.
l 다음 출현을 찾게 하기 위해 세번째 인수를 줄 수 있다. 이 때 index는 세번째 인수보다 크거나 같은 위치를 리턴한다.
-> $where = index(“hello world”, “l”); # 2를 리턴
$where = index(“hello world”, “l”, 0); # 동일
$where = index(“hello world”, “l”, 1); # 여전히 동일
$where = index(“hello world”, “l”, 3); # 이제 3을 리턴
$where = index(“hello world”, “o”, 8); # -1을 리턴
rindex()를 사용할 경우 오른쪽부터 탐색할 수 있다.
-> $w = rindex(“hello world”, “he”); # $w는 0
$w = rindex(“hello world”, “l”); # $w는 9 (가장 오른쪽의 l)
l rindex도 선택한 위치보다 작거나 같은 곳에 있는 것을 얻도록 세번째 인수를 받는다
-> $w = rindex(“hello world”, “o”, 6); # $w는 4(6 이전의 첫번째 것)
$w = rindex(“hello world”, “o”, 3); # $w는 –1(3 앞에는 없음)
서브문자열의 추출과 대체
문자열의 한 부분을 뽑아낼 때, 정규 표현식을 사용하는 방법 말고도, 특정 부분이 항상 알려진 문자 위치에 있을 경우 substr()을 이용할 수 있다.
-> $s = substr($string, $start, $length); # 문자열 값, 시작위치, 길이를 인수로 받는다
-> $hello = “hello, world!”;
$grab = substr($hello, 3, 2); # $grab은 “lo”
$grab = substr($hello, 7, 100); # 7에서 끝까지, 혹은 “world!”
l 문자열의 수가 0이면, 빈 문자열이 리턴된다.
l 시작 위치 또는 마지막 위치가 0보다 작으면, 위치는 문자열의 끝에서 그 수만큼의 문자를 헤아린 위치이다. (시작 위치가 –1, 길이가 1이면 마지막 문자를 의미한다)
-> $stuff = substr(“a very long string”, -3, 3); # 마지막 세 문자
$stuff = substr(“a very long string”, -3, 1); # 문자 “i”
l 시작 위치가 문자열의 시작 이전이면 문자열의 시작이 시작 위치가 된다.(마치 시작 위치로 0을 사용한 것 처럼)
l 시작 위치가 아주 큰 양수이면, 항상 빈 문자열이 리턴된다.
l 길이 인수의 생략은 그 인수에 대해 아주 큰 수를 사용한 것과 동일하다. (이는 선택한 위치에서 문자열의 끝까지 모든 것을 잡는다)
l substr로의 첫번째 인수가 스칼라 변수이면, substr 자체가 할당 연산자의 왼쪽에 나타날 수 있다.
-> $hw = “hello world!”;
substr($hw, 0, 5) = “howdy”; # $hw는 이제 “howdy world!”
l 대체 텍스트는 필요에 따라 자동으로 늘어나거나 줄어든다
-> substr($hw, 0, 5) = “hi”; # $hw는 이제 “hi world!”
substr($hw, -6, 5) = “nationwide news”; # “world”를 대체
sprintf()로 데이터 포맷팅 하기
sprintf 함수는 인수에 대해서 printf와 동일하나 printf에 의해 출력된 것을 단일 문자열로서 리턴한다.
-> $result = sprintf(“X%05d”, $y); # X뒤에 5자리 0으로 채워진 $y값으로 된 문자열
고급 정렬
perl에서는 정렬을 하기위해서 일반적으로 비교 서브 루틴을 만든다.
-> sub by_number {
if ($a < $b) {
return –1;
} elseif ($a== $b) {
return 0;
} elseif ($a > $b) {
return 1;
}
}
-> @somelist = (1, 2, 4, 8, 16, 32, 64, 128, 256);
@wronglist = sort @somelist; # @wronglist 는 (1. 128, 16, 2, 256, 32, 4, 64, 8)
@rightlist = sort by_number @wronglist;
# @rightlist는 이제 (1, 2, 4, 8, 16, 32, 64, 128, 256) “sort by number”
l <=> 를 perl에서는 spaceship 연산자라 부르며, 앞의 루틴을 한번에 처리할 수 있다
-> sub by_number {
$a <=> $b;
}
-> @rightlist = sort { $a <=> $b } @wronglist; # 이렇게 줄여 쓰는 것도 가능하다
l cmp 연산자는 숫자를 비교할 때 <=> 연산자와 비슷한 기능을 하며, 두 인수의 상대적인 문자열 비교에 따라 세 값 중의 하나를 리턴한다.
-> @result = sort {$a cmp $b} @somelist;
l “산술상 같지 않으면 숫자 순으로, 그 후에 문자열 순으로” 정렬하기 예
-> sub by_mostly_numeric {
($a <=> $b) || ($a cmp $b);
}
l 비교되는 값들이 전달되는 값들일 필요는 없다
-> # 로그인 이름과 실제 이름이 실제 이름의 순으로 정렬된 표를 출력하는 프로그램
@sortedkeys = sort by_names keys(%names); # 이름 값이 %name에 있다고 가정
sub by_names {
($names{$a} cmp $names{$b}) || ($a cmp $b);
}
foreach (@sortedkeys) {
print “$_ has a real name of $names{$_} ”;
}
변환
tr/// 을 사용하여 문자열의 모든 출현을 새로운 문자로 대체하거나, 어떤 문자의 모든 출현을 삭제할 수 있다. (s/// 로도 가능하지만 s///은 a를 b로 b를 a로 바꾸는 것은 할 수 없다)
-> tr/ab/ba/; # UNIX 쉘에서 tr ab ba <indata >outdata 와 같다.
l tr 연산자는 $_ 변수내의 모든 옛날 문자열의 문자들을 찾아 $_ 변수의 내용을 변경한다
-> $_ = “fred and barney”;
tr/fb/bf/; # $_는 이제 “bred and farney”
tr/abcde/ABCDE; # $_는 이제 “BrED AnD fArnEy”
tr/a-z/A-Z/; # $_는 이제 “BRED AND FARNEY”
l 새로운 문자열이 예전 문자열보다 짧다면 새로운 문자열의 마지막 문자는 문자열이 같은 길이가 되도록 반복된다
-> $_ = “fred and barney”;
tr/a-z/x/; # $_는 이제 “xxxx xxx xxxxxx”
tr///d 처럼 끝에 d를 추가할 경우 마지막 문자는 반복되지 않는다.
-> $_ = “fred and barney”;
tr/a-z/ABCDE/d; # $_는 이제 “ED AD BAE”
# 새로운 리스트에 대응되는 문자가 없기 때문에 e 뒤의 문자가 사라지고, 공백은 예전 리
# 스트에서 나타나지 않으므로 영향을 미치지 않음. UNIX 쉘에서 tr –d 명령과 유사
l tr/// 연산자의 리턴값은 옛날 문자열에 의해 일치된 문자의 수이고, 문자들을 그 자신으로 바꿈으로써 문자열 내에 있는 문자의 수를 얻을 수 있다.
-> $_ = “fred and barney”;
$count = tr/a-z//; # $_는 변화가 없으나, $count는 13
$count2 = tr/a-z/A-Z/; # $_는 대문자로 되고, $count2는 13
tr///c 는 모든 256문자에 대한 옛날 문자열의 보(complement)를 의미한다. 옛날 문자열에서 리스트 된 임의의 문자는 모든 가능한 문자들의 집합에서 제거된다. 나머지 문자들이 가장 낮은 것에서 높은 것의 순으로 나열되어 최종적인 문자열을 만든다.
-> $_ = “fred and barney”;
$count = tr/a-z//c; # $_는 변화가 없으나 $count는 2
tr/a-z/_/c; # $_는 이제 “fred_and_barney” (비문자 “ ”=> “_”)
tr/a-z//cd; # $_는 이제 “fredandbarney” (비문자를 제거)
l 옵션은 결합해서 사용 가능하다
tr///s 는 변환된 결과 문자에서 복수개의 연속적인 동일한 사본들을 하나로 압축한다.
-> $_ = “aaabbbcccdefghi”;
tr/defghi/abcddd/s; # $_는 이제 “aaabbbcccabcd”
-> $_ = “fred and barney, Wilma and betty”;
tr/a-z/X/s; # $_는 이제 “X X X, X X X”
$_ = “fred and barney, Wilma and betty”;
tr/a-z/_/cs; # $_는 이제 “fred_and_barney_Wilma_and_betty”
l tr 연산자도 =~ 연산자를 사용하여 $_ 이외의 다른 문자열을 목표로 할 수 있다.
-> $names = “fred and barney”;
$names =~ tr/aeiou/X/; # $_는 이제 “frXd Xnd bXrnXy”