Perl Study #10

[ 다른 데이터 변환 ]

 

서브 문자열 찾기

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”

답글 남기기

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