UTF-8이전작업/문자열잘라내기 페이지의 소스 보기
마지막으로 [b]
-- Loading page list... --
내용출력
로그인[l]
Diary
[f]
최근변경내역
[r]
페이지목록[i]
횡설수설[2]
게시판[3]
링크
수정할 수 없습니다: UTF-8이전작업/문자열잘라내기 는 읽기 전용 페이지입니다.
== # 문자열 잘라내기 == 어떤 문자열을, 자기가 원하는 만큼의 길이만큼 앞부분을 잘라내는 법 === # EUC-KR 위키의 경우 === 원하는 바이트만큼 잘라내고, 만일 제일 끝 바이트가 한글(2바이트)의 첫바이트일 경우, 그 바이트를 마저 잘라낸다. ext1 버전에서 사용된 방법 {{{#!vim perl # 트랙백 내용을 처음 252바이트만큼 잘라내기 $excerpt = substr($excerpt, 0, 252); $excerpt =~ s/(([\x80-\xff].)*)[\x80-\xff]?$/$1/; # 마지막 바이트 처리 }}} === # encoding에 따라서 다르게 처리하기 === UTF-8이 되면 한 글자가 2바이트일 수도 있고 3바이트일 수도 있으므로 위의 방법으로는 제대로 잘리지 않는다. 존재하지 않는 페이지의 경우 페이지 이름의 "첫 글자"를 잘라내어서 거기에 링크를 걸어야 하는데, 별 수 없이 인코딩이 뭐냐에 따라서 다르게 처리했다. UTF-8의 경우는 첫 바이트를 보고, "그 바이트 뒤에 몇 개의 바이트가 더 와야 하나의 글자가 되는지"를 판단한 후, 해당 길이만큼 잘라내도록 하였었다. 아래 코드의 경우는 첫 한 글자만 뽑아내는 경우이고, 만일 여러 글자를 뽑아내기 위해서는 저 과정을 다시 뽑아내려는 갯수만큼 반복해야 했을 것이다. 더 이상 사용되지 않는 코드인데, 기록 보존 차원에서 여기 적어둠. {{{#!vim perl sub GetFirstCharLink { # 첫 글자에 링크를 거는 함수 my ($id, $name) = @_; my @trailingBytesForUTF8 = ( # ftp://ftp.unicode.org/Public/PROGRAMS/CVTUTF/ConvertUTF.c 에서 옮겨왔음 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 ); my ($mainpage, $slash, $page) = ($name =~ m/(?:(.*)(\/))?(.+)/); # utf-8 if ($HttpCharset =~ /utf-8|utf8/i) { my $length = $trailingBytesForUTF8[ord(substr($page,0,1))] + 1; # 첫 바이트를 보고 첫 글자의 길이를 계산 my $first = substr($page,0,$length); # 이게 첫 글자 my $tail = substr($page,$length); # 이게 나머지 문자열 return $mainpage . &GetEditLink($id,$slash.$first) . $tail; } # euc-kr if ($HttpCharset =~ /euc-kr/i) { # 이와 같이, 모든 인코딩에 대해 각각 처리해주어야 한다 -_-; my ($first, $tail) = ($page =~ /([a-zA-Z0-9]|[\x80-\xff][\x80-\xff])(.*)/); return $mainpage . &GetEditLink($id,$slash.$first) . $tail; } # default return &GetEditLink($id, $name); } }}} === # Perl의 유니코드 처리를 이용 === "가나다"라는 문자열은, EUC-KR에서는 "%B0%A1%B3%AA%B4%D9" (6바이트), UTF-8에서는 "%EA%B0%80%EB%82%98%EB%8B%A4" (9바이트)로 표현된다. 그런데, [[Perl]] 코드에서 "\x{AC00}\x{B098}\x{B2E4}"와 같이, 유니코드 테이블에서의 가,나,다의 인덱스를 적어주어서 표현할 경우, 이것은 바이트와 무관하게 "3글자"로 표현된다. 따라서 정규표현식에서 "."이 1개의 글자를 의미하기 때문에, 영어든 한글이든 뭐든간에 "."으로 한글자를 정확히 뽑아낼 수 있다. 문제는 "EUC-KR 또는 UTF-8로 된 스트링을 어떻게 저 유니코드 표현으로 바꾸느냐"였는데... 보아하니 저 유니코드 표현이라는 것이 바로 "UNICODE"라는 이름의 인코딩인 것 같더라. 즉 EUC-KR 또는 UTF-8에서 UNICODE로 인코딩 컨버트를 하면 되는 것이었음. (사실 이건 순전히 막무가내 테스트 도중에 요행히 발견한 것이라... 정확한 건지 모르겠다. UNICODE 인코딩의 경우 시스템의 big/little endian 에 따라서 또 달라지는 것 같던데...) 따라서, 위키에서 사용되는 인코딩(HttpCharset)을 UNICODE로 변환하여 문자열 처리를 한 후, 다시 출력할 때는 HttpCharset으로 재변환해주면, EUC-KR위키와 UTF-8위키 두 곳에서 다 잘 되는 것으로 보인다. 첫 글자에 링크 걸기는 아래와 같이 간단히 바뀐다. {{{#!vim perl # 첫 글자에 링크를 거는 함수 sub GetFirstCharLink { my ($id, $name) = @_; my ($mainpage, $slash, $page) = ($name =~ m/(?:(.*)(\/))?(.+)/); my ($first, $last) = &split_string($page, 1); # $page의 첫 1글자는 $first에, 나머지 문자열은 $last에 들어감 return $mainpage . &GetEditLink($id,$slash.$first) . $last; } }}} 위에 사용된 split_string 함수는 [[Perl/문자열나누기]]에 적어 두었음 === # 의견 ===
---- [[위키위키분류]]
UTF-8이전작업/문자열잘라내기
페이지로 돌아가기 |
다른 수정본 보기