Perl/문자열나누기 페이지의 소스 보기
마지막으로 [b]
-- Loading page list... --
내용출력
로그인[l]
Diary
[f]
최근변경내역
[r]
페이지목록[i]
횡설수설[2]
게시판[3]
링크
수정할 수 없습니다: Perl/문자열나누기 는 읽기 전용 페이지입니다.
== # 하나의 스트링을 쪼개어서 배열로 만들기 == {{{#!vim perl @변수 = split( / 구분자 /, $변수); }}} * $변수의 내용을 구분자에 의해 분리하여 배열을 반환한다. * 구분자는 [[/정규표현식]] 사용가능 {{{#!vim perl @변수 = split( / (구분자) /, $변수); }}} * 구분자에 괄호가 들어가면 매치되는 구분자 역시 배열의 원소가 된다. === # split에 lookaround를 사용하여 특수한 경우가 생기지 않게 하라 === * 원문: [http://www.effectiveperlprogramming.com/blog/1411 Use lookarounds to split to avoid special cases | The Effective Perler] * 번역, 요약 * 원문의 테스트 코드를, 출력 결과를 알아보기 쉽도록 수정을 했음 구분자가 단일 캐릭터일 때. 쉽다. {{{#!vim perl use v5.10; my @letters = split /:/, 'a:b:c:d:e'; say join(":", @letters); }}} {{{#!vim a:b:c:d:e }}} 구분자 패턴의 길이가 2이상이거나 가변적일 때도, 무난하다. {{{#!vim perl my @cats = split /\s+/, 'Buster Mimi Roscoe'; say join(":", @cats); }}} {{{#!vim Buster:Mimi:Roscoe }}} 구분자가 좌우대칭인 형태, 즉 각 값의 시작과 끝을 표시하는 마크가 있는 상황이라면 좀 복잡해진다. 값들 사이에 있는 패턴을 가지고 쪼갤 경우 첫번째 값의 앞과 마지막 값의 뒤에 있는 게 지워지지 않는다. {{{#!vim perl my @cats = split />, '
'; say join(":", @cats); }}} {{{#!vim
}}} 이렇게 남은 것은
split
한 후에 따로 처리하고자 할 수도 있다: {{{#!vim perl my @cats = split />, '
'; $cats[0] =~ s//; $cats[-1] =~ s/>//; say join(":", @cats); }}} 물론 이렇게 해도 동작은 하지만, 이렇게 따로 처리해야 하는 특별한 경우를 만들지 않는 것이 좋다. 제거하려는 캐릭터들 모두에 매치되도록 구분자를 지정할 경우, 한가지 문제가 생긴다. 제일 앞에 있는 구분자 앞쪽에 빈 스트링 하나가 첫번째 원소가 된다: (출력 부분에
buster
앞에 콜론이 붙은 것에 유의) {{{#!vim perl my @cats = split /><|\A<|>\z/, '
'; say join(":", @cats); }}} {{{#!vim :buster:mimi:roscoe }}} 첫번째 필드를 쉬프트시켜서 제거할 수 있으나, 역시 보기 좋지 않다: {{{#!vim perl my @cats = split /><|\A<|>\z/, '
'; shift @cats; say join(":", @cats); }}} 캐릭터들을 매치시키는 게 아니라, lookaround를 사용하여 이런 좌우대칭 형태 구분자의 사이에서 split을 하게 할 수 있다. lookaround는 스트링 내의 특정한 조건에 매치가 되며 캐릭터를 소모하지 않는다
. lookbehind와 lookahead
를 나란히 사용하여, 두 조건이 동시에 매치되는 지점에서 스트링을 쪼갤 수 있다. {{{#!vim perl my @cats = split /(?<=>)(?=<)/, '
'; say join(":", @cats); }}} {{{#!vim
:
:
}}} 위 출력결과에서는, 구분자 캐릭터들이 없어지지는 않았으나, 이제 각 원소들을 동일하게 처리하면 되며 특별히 처리할 케이스가 없다. {{{#!vim perl my @cats = # map { s/\A<|>\z//rg } # Perl 5.14 부터는 /r 옵션을 써서 이렇게도 가능 map { my $s = $_; $s =~ s/\A<|>\z//g; $s } split /(?<=>)(?=<)/, '
'; say join(":", @cats); }}} {{{#!vim buster:mimi:roscoe }}} 좀 더 복잡하게, 각 필드가 따옴표로 둘러쌓여 있고, 다시 쉼표로 구분되어 있는 경우: {{{#!vim perl my @cats = map { my $s = $_; $s =~ s/\A"|"\z//g; $s } split /(?<="),(?=")/, '"Buster","Mimi","Roscoe"'; say join(":", @cats); }}} 쉼표와 따옴표를 한번에 제거할 수 있는 더 복잡한 정규표현식을 만들 수도 있겠지만, 지금처럼 단순한 단계 두 번을 거치는 것에 비해, 코드를 읽고 유지하기에 어려울 것이다. 요점: * 구분자를 한 번에 제거할 필요는 없다 * lookbehind와 lookahead를 나란히 사용하여 스트링 내에 특정한 위치를 지정할 수 있다 === # split의 특별한 케이스 === * 원문: [http://www.effectiveperlprogramming.com/blog/1416 Know split’s special cases | The Effective Perler] split 에 구분자로 주어지는 패턴이 다음과 같은 경우는 특별하게 동작한다: * 빈 패턴
//
은 문자열을 캐릭터들로 쪼갠다. * 빈 스트링, zero-width로 매치되는 패턴(
?
,
*
, lookaround 등을 사용한)도 문자열을 캐릭터들로 쪼갠다. * 따옴표로 둘러쌓인 단일 스페이스
' '
또는
" "
는 공백을 기준으로 문자열을 분리하되, 제일 앞에 있는 빈 필드는 버린다. * 앵커
/^/
는 문자열을 라인 단위로 쪼갠다. (정확히 이 형태일 때만 그렇고,
/^(?=.)/
와 같이 패턴에 다른 게 섞인다면 - 설령 제대로 매치되더라도 - 동작하지 않는다. 이 때는 패턴에
/m
플래그를 붙여주어야 한다) {{{#!vim perl my $str = ' Buster and Mimi'; print join(":", split //, $str); # 빈 패턴 # : :B:u:s:t:e:r: :a:n:d: :M:i:m:i print join(":", split /z*/, $str); # 빈 스트링 # : :B:u:s:t:e:r: :a:n:d: :M:i:m:i print join(":", split / /, $str); # 일반적인 공백 패턴 # ::Buster:and:Mimi # 앞에 ""가 두 번 들어감 print join(":", split ' ', $str); # 따옴표로 둘러싼 단일 공백의 경우 # Buster:and:Mimi # 앞에 두 개의 ""가 없어짐 $str = "Line 1\nLine 2\nLine 3"; print join(":", split /^/, $str); # Line 1 # :Line 2 # :Line 3 }}} == # 하나의 스트링을 인코딩에 관계없이 일정 갯수의 문자로 나누기 == 2007년에 끙끙댔던 문제인데, 막상 답을 알고 나니 매우 간단해져서, 과거 내용은 삭제함 * Perl 5.8 이후로는, Encode 모듈이 있으므로, 문자열을 일단 decode하고 나면 한글이든 영문이든 어떤 캐릭터든 "글자 한 개"로 간주되니까 substr 을 쓰든 정규표현식을 쓰든 그냥 쪼개면 된다. {{{#!vim perl # 이 파일은 cp949로 저장되어 있음 use Encode; my $str = decode("cp949", "English와 한글"); my $length = length($str); for (my $i = 1; $i < $length; $i++) { printf "%2d : ", $i; print "[", encode("cp949", substr($str, 0, $i)), "] [", encode("cp949", substr($str, $i)), "]\n"; } }}} {{{#!vim 1 : [E] [nglish와 한글] 2 : [En] [glish와 한글] 3 : [Eng] [lish와 한글] 4 : [Engl] [ish와 한글] 5 : [Engli] [sh와 한글] 6 : [Englis] [h와 한글] 7 : [English] [와 한글] 8 : [English와] [ 한글] 9 : [English와 ] [한글] 10 : [English와 한] [글] }}} * Perl 5.6과 그 이전 버전에서는 (굳이 그 오래된 버전을 써야 한다면) Text::Iconv 모듈을 사용해서 UTF-16 등 한 문자가 2바이트로 고정된 인코딩으로 바꾸고, 2바이트 단위로 처리한 다음에 다시 원래 인코딩으로 바꿔주면 되겠다. == 기타 ==
----
---- [[컴퓨터분류]]
Perl/문자열나누기
페이지로 돌아가기 |
다른 수정본 보기