File Coverage

blib/lib/ShiftJIS/String.pm
Criterion Covered Total %
statement 316 323 97.8
branch 281 316 88.9
condition 63 70 90.0
subroutine 50 52 96.1
pod 38 40 95.0
total 748 801 93.3


line stmt bran cond sub pod time code
1             package ShiftJIS::String;
2              
3 25     25   38200 use Carp;
  25         72  
  25         2598  
4 25     25   139 use strict;
  25         45  
  25         992  
5 25     25   211 use vars qw($VERSION $PACKAGE @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
  25         41  
  25         61947  
6              
7             $VERSION = '1.11';
8             $PACKAGE = 'ShiftJIS::String'; # __PACKAGE__
9              
10             require Exporter;
11             @ISA = qw(Exporter);
12              
13             %EXPORT_TAGS = (
14             issjis => [qw/issjis/],
15             string => [qw/length index rindex strspn strcspn strrev substr strsplit/],
16             'span' => [qw/strspn strcspn rspan rcspan/],
17             'trim' => [qw/trim ltrim rtrim/],
18             'cmp' => [qw/strcmp strEQ strNE strLT strLE strGT strGE strxfrm/],
19             ctype => [qw/toupper tolower/],
20             'tr' => [qw/mkrange strtr trclosure/],
21             'kana' => [qw/hi2ka ka2hi hiXka/],
22             'H2Z' => [qw/kataH2Z kanaH2Z hiraH2Z spaceH2Z/],
23             'Z2H' => [qw/kataZ2H kanaZ2H hiraZ2H spaceZ2H/],
24             );
25              
26             $EXPORT_TAGS{all} = [ map @$_, values %EXPORT_TAGS ];
27             $EXPORT_TAGS{core} = [ map @$_, @EXPORT_TAGS{qw/issjis string cmp ctype tr/} ];
28              
29             @EXPORT_OK = @{ $EXPORT_TAGS{all} };
30             @EXPORT = ();
31              
32             my $Char = '(?:[\x81-\x9F\xE0-\xFC][\x00-\xFF]|[\x00-\xFF])';
33             my $White = "\t\n\r\f\x20\x81\x40";
34              
35             ##
36             ## issjis(LIST)
37             ##
38             sub issjis {
39 18     18 1 1343 for (@_) {
40 23         115 my $str = $_;
41 23         34285 $str =~ s/[\x00-\x7F\xA1-\xDF]|
42             [\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC]//gx;
43 23 100       106 return '' if CORE::length($str);
44             }
45 11         26 return 1;
46             }
47              
48             ##
49             ## length(STRING)
50             ##
51             sub length ($) {
52 1467     1467 1 4896 my $str = shift;
53 1467         156845 return 0 + $str =~ s/$Char//go;
54             }
55              
56             ##
57             ## strrev(STRING)
58             ##
59             sub strrev ($) {
60 23     23 1 660 my $str = shift;
61 23         34433 join '', reverse $str =~ /$Char/go;
62             }
63              
64             ##
65             ## index(STRING, SUBSTR; POSITION)
66             ##
67             sub index($$;$) {
68 97     97 1 2225 my $cnt = 0;
69 97         144 my($str, $sub) = @_;
70 97         153 my $len = &length($str);
71 97 100       294 my $pos = @_ == 3 ? $_[2] : 0;
72 97 100       195 if ($sub eq "") {
73 11 100       42 return $pos <= 0 ? 0 : $len <= $pos ? $len : $pos;
    100          
74             }
75 86 100       171 return -1 if $len < $pos;
76              
77 73         87 my $sublen = CORE::length($sub);
78 73 50 100     1333 $str =~ s/^$Char//o ? $cnt++ : croak "${PACKAGE}::index"
79             while CORE::length($str) && $cnt < $pos;
80 73 50 100     931915 $str =~ s/^$Char//o ? $cnt++ : croak "${PACKAGE}::index"
81             while CORE::length($str) && CORE::substr($str,0,$sublen) ne $sub;
82 73 100       768 return CORE::length($str) ? $cnt : -1;
83             }
84              
85             ##
86             ## rindex(STRING, SUBSTR; POSITION)
87             ##
88             sub rindex($$;$) {
89 92     92 1 1385 my $cnt = 0;
90 92         138 my($str, $sub) = @_;
91 92         171 my $len = &length($str);
92 92 100       214 my $pos = @_ == 3 ? $_[2] : $len;
93 92 100       172 if ($sub eq "") {
94 11 100       65 return $pos <= 0 ? 0 : $len <= $pos ? $len : $pos;
    100          
95             }
96 81 100       179 return -1 if $pos < 0;
97              
98 58         72 my $sublen = CORE::length($sub);
99 58         65 my $ret = -1;
100 58   100     233 while ($cnt <= $pos && CORE::length($str)) {
101 100367 100       214208 $ret = $cnt if CORE::substr($str,0,$sublen) eq $sub;
102 100367 50       1029507 $str =~ s/^$Char//o ? $cnt++ : croak "${PACKAGE}::rindex";
103             }
104 58         211 return $ret;
105             }
106              
107             ##
108             ## strspn(STRING, SEARCHLIST)
109             ##
110             sub strspn($$) {
111 19     19 1 2833 my($str, $lst) = @_;
112 19         29 my $ret = 0;
113 19         25 my(%lst);
114 19         245 @lst{ $lst =~ /$Char/go } = ();
115 19         140 while ($str =~ /($Char)/go) {
116 50060 100       86963 last if ! exists $lst{$1};
117 50045         123679 $ret++;
118             }
119 19         109 return $ret;
120             }
121              
122             ##
123             ## strcspn(STRING, SEARCHLIST)
124             ##
125             sub strcspn($$) {
126 8     8 1 429 my($str, $lst) = @_;
127 8         11 my $ret = 0;
128 8         11 my(%lst);
129 8         134 @lst{ $lst=~ /$Char/go } = ();
130 8         123 while ($str =~ /($Char)/go) {
131 50017 100       83745 last if exists $lst{$1};
132 50013         116988 $ret++;
133             }
134 8         38 return $ret;
135             }
136              
137             ##
138             ## rspan(STRING, SEARCHLIST)
139             ##
140             sub rspan($$) {
141 23     23 1 1148 my($str, $lst) = @_;
142 23         31 my $ret = 0;
143 23         22 my $cnt = 0;
144 23         26 my($found, %lst);
145 23         227 @lst{ $lst =~ /$Char/go } = ();
146 23         140 while ($str =~ /($Char)/go) {
147 100264 100 100     312115 $ret = $cnt if exists $lst{$1} && !$found;
148 100264         125195 $found = exists $lst{$1};
149 100264         259822 $cnt++;
150             }
151 23 100       138 return $found ? $ret : $cnt;
152             }
153              
154             ##
155             ## rcspan(STRING, SEARCHLIST)
156             ##
157             sub rcspan($$) {
158 10     10 1 456 my($str, $lst) = @_;
159 10         14 my $ret = 0;
160 10         12 my $cnt = 0;
161 10         13 my($found, %lst);
162 10         133 @lst{ $lst =~ /$Char/go } = ();
163 10         117 while ($str =~ /($Char)/go) {
164 50059 100 100     182616 $ret = $cnt if !exists $lst{$1} && $found;
165 50059         62017 $found = exists $lst{$1};
166 50059         128127 $cnt++;
167             }
168 10 100       60 return !$found ? $ret : $cnt;
169             }
170              
171             ##
172             ## ltrim(STRING; SEARCHLIST; USE_COMPLEMENT)
173             ##
174             sub ltrim($;$$) {
175 44     44 1 3760 my($str, $lst, $c) = @_;
176 44 100       112 $lst = $White if ! defined $lst;
177 44         51 my $pos = 0;
178 44         54 my(%lst);
179 44         671 @lst{ $lst =~ /$Char/go } = ();
180 44         267 while ($str =~ /($Char)/go) {
181 100212 100       230819 last if $c ? exists $lst{$1} : ! exists $lst{$1};
    100          
182 100190         302518 $pos += CORE::length($1);
183             }
184 44         254 return CORE::substr($str,$pos);
185             }
186              
187             ##
188             ## rtrim(STRING; SEARCHLIST; USE_COMPLEMENT)
189             ##
190             sub rtrim($;$$) {
191 44     44 1 3562 my($str, $lst, $c) = @_;
192 44 100       124 $lst = $White if ! defined $lst;
193 44         52 my $ret = 0;
194 44         63 my $pos = 0;
195 44         47 my($prefound, $curfound, %lst);
196 44         532 @lst{ $lst=~ /$Char/go } = ();
197 44         243 while ($str =~ /($Char)/go) {
198 50307 100       91203 $curfound = $c ? ! exists $lst{$1} : exists $lst{$1};
199 50307 100 100     174012 $ret = $pos if $curfound && !$prefound;
200 50307         53860 $prefound = $curfound;
201 50307         146810 $pos += CORE::length($1);
202             }
203 44 100       281 return CORE::substr($str, 0, $prefound ? $ret : $pos);
204             }
205              
206             ##
207             ## trim(STRING; SEARCHLIST; USE_COMPLEMENT)
208             ##
209             sub trim($;$$) {
210 22     22 1 3619 my($str, $lst, $c) = @_;
211 22         45 rtrim(ltrim($str, $lst, $c), $lst, $c);
212             }
213              
214              
215             ##
216             ## substr(STRING or SCALAR REF, OFFSET; LENGTH)
217             ## substr(SCALAR, OFFSET, LENGTH, REPLACEMENT)
218             ##
219             sub substr($$;$$) {
220 1258     1258 1 31827 my($ini, $fin, $except);
221 1258         1972 my($arg, $off, $len, $rep) = @_;
222 1258 100       2361 my $str = ref $arg ? $$arg : $arg;
223              
224 1258         1973 my $slen = &length($str);
225 1258 100       2923 $except = 1 if $slen < $off;
226 1258 100       2140 if (@_ == 2) {$len = $slen - $off }
  50         64  
227             else {
228 1208 100 100     2894 $except = 1 if $off + $slen < 0 && $len + $slen < 0;
229 1208 100 100     4066 $except = 1 if 0 <= $len && $off + $len + $slen < 0;
230             }
231 1258 100       7527 if ($except) {
232 55 50       85 if (@_ > 3) {
233 0         0 croak "$PACKAGE outside of string in substr";
234 55         145 } else { return }
235             }
236 1203 100       2066 $ini = $off < 0 ? $slen + $off : $off;
237 1203 100       1896 $fin = $len < 0 ? $slen + $len : $ini + $len;
238 1203 100       2023 $ini = 0 if $ini < 0;
239 1203 100       1939 $fin = $ini if $ini > $fin;
240 1203 50       1956 $ini = $slen if $slen < $ini;
241 1203 100       1974 $fin = $slen if $slen < $fin;
242              
243 1203         1323 my $cnt = 0;
244 1203         1147 my $plen = 0;
245 1203         1165 my $clen = 0;
246 1203         4260 while ($str =~ /($Char)/go) {
247 87799 100       154681 if ($cnt < $ini) { $plen += CORE::length($1) }
  64381 100       115265  
248 22646         28066 elsif($cnt < $fin) { $clen += CORE::length($1) }
249 772         960 else { last }
250 87027         236417 $cnt++;
251             }
252 1203 100       2280 if (@_ > 3) {
253 357         897 $_[0] = CORE::substr($str, 0, $plen) .
254             $rep. CORE::substr($str, $plen + $clen);
255             }
256 1203 100       5903 return ref $arg
257             ? \ CORE::substr($$arg, $plen, $clen)
258             : CORE::substr($str, $plen, $clen);
259             }
260              
261             ##
262             ## strtr(STRING or SCALAR REF, SEARCHLIST, REPLACEMENTLIST;
263             ## MODIFIER, PATTERN, TOPATTERN)
264             ##
265             my %Cache;
266              
267 0 0   0 0 0 sub getStrtrCache { wantarray ? %Cache : \%Cache }
268              
269             sub strtr($$$;$$$) {
270 619     619 1 29479 my $str = shift;
271 619 50 66     3388 my $coderef = (defined $_[2] && $_[2] =~ /o/)
      0        
272             ? ( $Cache{ join "\xFF", @_ } ||= trclosure(@_) )
273             : trclosure(@_);
274 619         1268 &$coderef($str);
275             }
276              
277              
278             ##
279             ## trclosure(SEARCHLIST, REPLACEMENTLIST; MODIFIER, PATTERN, TOPATTERN)
280             ##
281             sub trclosure($$;$$$)
282             {
283 907     907 1 2262 my(@fr, @to, $noxs, $r, $R, $c, $d, $s, $h, $i, %hash);
284 907         1982 my($fr, $to, $mod, $re, $tore) = @_;
285 907   100     2313 $mod ||= ''; # '0' is not supposed.
286              
287 25     25   35935 $noxs = $[ <= CORE::index($mod, 'n'); # no-op in the Non-XS version.
  25         12152  
  25         132175  
  907         3399  
288 907         2750 $h = $[ <= CORE::index($mod, 'h');
289 907         1942 $r = $[ <= CORE::index($mod, 'r');
290 907         1778 $R = $[ <= CORE::index($mod, 'R');
291              
292 907 100       1780 if (ref $fr) {
293 1         3 @fr = @$fr;
294 1 50       9 $re = defined $re
295             ? "$re|$Char"
296             : join('|', map(quotemeta($_), @$fr), $Char);
297             } else {
298 906 100       2145 $fr = mkrange($fr, $r) unless $R;
299 906 100       2022 $re = defined $re ? "$re|$Char" : $Char;
300 906         29765 @fr = $fr =~ /\G$re/g;
301             }
302 907 100       2498 if (ref $to) {
303 1         3 @to = @$to;
304 1 50       8 $tore = defined $tore
305             ? "$tore|$Char"
306             : join('|', map(quotemeta($_), @$to), $Char);
307             } else {
308 906 100       2367 $to = mkrange($to, $r) unless $R;
309 906 100       1662 $tore = defined $tore ? "$tore|$Char" : $re;
310 906         33136 @to = $to =~ /\G$tore/g;
311             }
312              
313 907         4691 $c = $[ <= CORE::index($mod, 'c');
314 907         1903 $d = $[ <= CORE::index($mod, 'd');
315 907         2051 $s = $[ <= CORE::index($mod, 's');
316 907         1582 my $modes = $s * 4 + $d * 2 + $c;
317              
318 907         2081 for ($i = 0; $i < @fr; $i++) {
319 27894 100       55047 next if exists $hash{ $fr[$i] };
320 27050 100 100     121351 $hash{ $fr[$i] } = @to
    100          
    100          
    100          
321             ? defined $to[$i] ? $to[$i] : $d ? '' : $to[-1]
322             : $d && !$c ? '' : $fr[$i];
323             }
324              
325             return
326             $modes == 0 || $modes == 2 ?
327             sub { # $c: false, $d: true/false, $s: false, $mod: 0 or 2
328 2186     2186   9012 my $str = shift;
329 2186         2460 my $cnt = 0; my %cnt = ();
  2186         3233  
330 2186 100       14284 (ref $str ? $$str : $str) =~ s{($re)}{
331 551744 100       1952501 exists $hash{$1}
    100          
332             ? ($h ? ++$cnt{$1} : ++$cnt, $hash{$1})
333             : $1;
334             }ge;
335 2186 100       73956 return $h
    100          
    100          
336             ? wantarray ? %cnt : \%cnt
337             : ref $str ? $cnt : $str;
338             } :
339              
340             $modes == 1 ?
341             sub { # $c: true, $d: false, $s: false, $mod: 1
342 74     74   87 my $str = shift;
343 74         84 my $cnt = 0; my %cnt = ();
  74         96  
344 74 50       470 (ref $str ? $$str : $str) =~ s{($re)}{
345 2327 100       8575 exists $hash{$1} ? $1
    100          
    100          
346             : ($h ? ++$cnt{$1} : ++$cnt, @to) ? $to[-1] : $1;
347             }ge;
348 74 50       854 return $h
    50          
    100          
349             ? wantarray ? %cnt : \%cnt
350             : ref $str ? $cnt : $str;
351             } :
352              
353             $modes == 3 || $modes == 7 ?
354             sub { # $c: true, $d: true, $s: true/false, $mod: 3 or 7
355 147     147   160 my $str = shift;
356 147         148 my $cnt = 0; my %cnt = ();
  147         178  
357 147 100       910 (ref $str ? $$str : $str) =~ s{($re)}{
358 4663 100       13366 exists $hash{$1} ? $1 : ($h ? ++$cnt{$1} : ++$cnt, '');
    100          
359             }ge;
360 147 50       1317 return $h
    100          
    100          
361             ? wantarray ? %cnt : \%cnt
362             : ref $str ? $cnt : $str;
363             } :
364              
365             $modes == 4 || $modes == 6 ?
366             sub { # $c: false, $d: true/false, $s: true, $mod: 4 or 6
367 147     147   161 my $str = shift;
368 147         158 my $cnt = 0; my %cnt = ();
  147         186  
369 147         159 my $pre = '';
370 147 100       829 (ref $str ? $$str : $str) =~ s{($re)}{
371 4659 50 100     16175 exists $hash{$1} ? ($h ? ++$cnt{$1} : ++$cnt,
    100          
    100          
372             $hash{$1} eq '' || $hash{$1} eq $pre
373             ? '' : ($pre = $hash{$1})
374             ) : ($pre = '', $1);
375             }ge;
376 147 0       1460 return $h
    100          
    50          
377             ? wantarray ? %cnt : \%cnt
378             : ref $str ? $cnt : $str;
379             } :
380              
381             $modes == 5 ?
382             sub { # $c: true, $d: false, $s: true, $mod: 5
383 73     73   90 my $str = shift;
384 73         86 my $cnt = 0; my %cnt = ();
  73         98  
385 73         83 my $pre = '';
386 73         70 my $tmp;
387 73 100       466 (ref $str ? $$str : $str) =~ s{($re)}{
388 2319 50       9460 exists $hash{$1}
    100          
    100          
    100          
389             ? ($pre = '', $1)
390             : ($h ? ++$cnt{$1} : ++$cnt,
391             $tmp = @to ? $to[-1] : $1,
392             $tmp eq $pre ? '' : ($pre = $tmp)
393             );
394             }ge;
395 73 0       850 return $h
    100          
    50          
396             ? wantarray ? %cnt : \%cnt
397             : ref $str ? $cnt : $str;
398             } :
399 0     0   0 sub { croak "$PACKAGE Panic! Invalid closure in trclosure!\n" }
400 907 50 100     12581 }
    100 100        
    100 100        
    100          
    100          
401              
402              
403             sub sjis_display ($) { # for err-msg
404 4     4 0 5 my $c = shift;
405 4 100 33     404 $c == 0 ? '\0' :
    50          
    50          
406             $c < 0x20 || $c == 0x7F ? sprintf("\\x%02x", $c) :
407             $c > 0xFF ? pack('n', $c) : chr($c);
408             }
409              
410 428 100   428   1198 sub __ord ($) { CORE::length($_[0]) > 1 ? unpack('n', $_[0]) : ord($_[0]) }
411              
412             sub __expand {
413 214     214   241 my($ini, $fin, $i, $ch, @retv);
414 0         0 my($fin_f,$fin_t,$ini_f,$ini_t);
415 214         321 my($fr, $to, $rev) = @_;
416 214 100       369 if ($fr > $to) {
417 14 100       22 if($rev){ ($fr,$to) = ($to,$fr) }
  12         22  
418             else {
419 2         10 croak sprintf "$PACKAGE Invalid character range %s-%s",
420             sjis_display($fr), sjis_display($to);
421             }
422 200         252 } else { $rev = 0 }
423 212 100       440 if ($fr <= 0x7F) {
424 152 50       273 $ini = $fr < 0x00 ? 0x00 : $fr;
425 152 100       284 $fin = $to > 0x7F ? 0x7F : $to;
426 152         446 for ($i = $ini; $i <= $fin; $i++) { push @retv, chr($i) }
  4063         9586  
427             }
428 212 100       526 if ($fr <= 0xDF) {
429 155 100       343 $ini = $fr < 0xA1 ? 0xA1 : $fr;
430 155 100       270 $fin = $to > 0xDF ? 0xDF : $to;
431 155         390 for ($i = $ini; $i <= $fin; $i++) { push @retv, chr($i) }
  400         795  
432             }
433 212 100       432 $ini = $fr < 0x8140 ? 0x8140 : $fr;
434 212 50       416 $fin = $to > 0xFCFC ? 0xFCFC : $to;
435 212 100       489 if ($ini <= $fin) {
436 61         191 ($ini_f,$ini_t) = unpack 'C*', pack 'n', $ini;
437 61         123 ($fin_f,$fin_t) = unpack 'C*', pack 'n', $fin;
438 61 50       129 $ini_t = 0x40 if $ini_t < 0x40;
439 61 50       114 $fin_t = 0xFC if $fin_t > 0xFC;
440 61 100       122 if ($ini_f == $fin_f) {
441 55         73 $ch = chr $ini_f;
442 55         123 for ($i = $ini_t; $i <= $fin_t; $i++) {
443 2820 100       8007 next if $i == 0x7F;
444 2807         7162 push @retv, $ch.chr($i);
445             }
446             } else {
447 6         22 $ch = chr($ini_f);
448 6         27 for ($i = $ini_t; $i <= 0xFC; $i++) {
449 690 100       1202 next if $i == 0x7F;
450 688         1837 push @retv, $ch.chr($i);
451             }
452 6         27 for ($i = $ini_f+1; $i < $fin_f; $i++) {
453 280 100 100     1127 next if 0xA0 <= $i && $i <= 0xDF;
454 152         179 $ch = chr($i);
455 152         25720 push @retv, map $ch.chr, 0x40..0x7E, 0x80..0xFC;
456             }
457 6         14 $ch = chr($fin_f);
458 6         22 for ($i = 0x40; $i <= $fin_t; $i++) {
459 662 100       1101 next if $i == 0x7F;
460 658         1555 push @retv, $ch.chr($i);
461             }
462             }
463             }
464 212 100       15556 return $rev ? reverse(@retv) : @retv;
465             }
466              
467              
468             ##
469             ## mkrange(STRING, BOOL)
470             ##
471             sub mkrange($;$) {
472 1456     1456 1 6331 my($s, @retv, $range, $min, $max);
473 1456         1860 my($self,$rev) = @_;
474 1456         1765 $self =~ s/^-/\\-/;
475 1456         1558 $range = 0;
476 1456         8910 foreach $s ($self =~ /\G(?:\\\\|\\-|$Char)/go) {
477 4205 100       5859 if ($range) {
478 214 50       631 if ($s eq '\\-') { $s = '-' }
  0 50       0  
479 0         0 elsif ($s eq '\\\\') { $s = '\\' }
480              
481 214 50       671 $min = @retv ? __ord(pop(@retv)) : 1;
482 214         423 $max = __ord($s);
483 214         410 push @retv, __expand($min,$max,$rev);
484 212         1562 $range = 0;
485             } else {
486 3991 100       9016 if ($s eq '-') { $range = 1 }
  219 100       390  
    50          
487 8         24 elsif ($s eq '\\-') { push @retv, '-' }
488 0         0 elsif ($s eq '\\\\') { push @retv, '\\'}
489 3764         6872 else { push @retv, $s }
490             }
491             }
492 1454 100       3850 push @retv, '-' if $range;
493 1454 100       18716 wantarray ? @retv : @retv ? join('', @retv) : '';
    100          
494             }
495              
496              
497             ##
498             ## spaceH2Z(STRING)
499             ##
500             sub spaceH2Z($) {
501 17     17 1 3528 my $str = shift;
502 17 100       88 my $len = CORE::length(ref $str ? $$str : $str);
503 17 100       479 (ref $str ? $$str : $str) =~ s/ /\x81\x40/g;
504 17 100       209 ref $str ? abs($len - CORE::length $$str) : $str;
505             };
506              
507             ##
508             ## spaceZ2H(STRING)
509             ##
510             ## tolower(STRING) and toupper(STRING)
511             ##
512             my $spaceZ2H = trclosure(' ', ' ');
513             my $toupper = trclosure('a-z', 'A-Z');
514             my $tolower = trclosure('A-Z', 'a-z');
515              
516 29     29 1 2877 sub spaceZ2H($) { &$spaceZ2H(@_) }
517 31     31 1 5362 sub toupper($) { &$toupper(@_) }
518 27     27 1 4623 sub tolower($) { &$tolower(@_) }
519              
520             ##
521             ## Kana Letters
522             ##
523             my $kataTRE = '(?:[\xB3\xB6-\xC4\xCA-\xCE]\xDE|[\xCA-\xCE]\xDF)';
524             my $hiraTRE = '(?:\x82\xA4\x81\x4A)'; # 'う゛'
525             my $kanaTRE = "(?:$hiraTRE|$kataTRE)";
526              
527             my $kataH
528             = '。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタ'
529             . 'チツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚'
530             . 'ガギグゲゴザジズゼゾダヂヅデドバビブベボパピプペポ'
531             . 'ヴイエワカケ';
532              
533             my $kataZH
534             = '。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタ'
535             . 'チツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゛゜'
536             . 'ガギグゲゴザジズゼゾダヂヅデドバビブベボパピプペポ'
537             . 'ヴヰヱヮヵヶ';
538              
539             my $hiraZH
540             = '。「」、・をぁぃぅぇぉゃゅょっーあいうえおかきくけこさしすせそた'
541             . 'ちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわん゛゜'
542             . 'がぎぐげござじずぜぞだぢづでどばびぶべぼぱぴぷぺぽ'
543             . 'う゛ゐゑゎかけ';
544              
545             my $kataH2Z = trclosure($kataH, $kataZH, 'R', $kanaTRE);
546             my $hiraH2Z = trclosure($kataH, $hiraZH, 'R', $kanaTRE);
547             my $kataZ2H = trclosure($kataZH, $kataH, 'R', $kanaTRE);
548             my $kanaZ2H = trclosure($hiraZH.$kataZH, $kataH.$kataH, 'R', $kanaTRE);
549             my $hiraZ2H = trclosure($hiraZH, $kataH, 'R', $kanaTRE);
550              
551             my $kataZ
552             = 'ヲァィゥェォャュョッアイウエオカキクケコサシスセソタ'
553             . 'チツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン'
554             . 'ガギグゲゴザジズゼゾダヂヅデドバビブベボパピプペポ'
555             . 'ヴヰヱヮヵヶヽヾ';
556              
557             my $hiraZ
558             = 'をぁぃぅぇぉゃゅょっあいうえおかきくけこさしすせそた'
559             . 'ちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわん'
560             . 'がぎぐげござじずぜぞだぢづでどばびぶべぼぱぴぷぺぽ'
561             . 'う゛ゐゑゎかけゝゞ';
562              
563             my $hiXka = trclosure($kataZ.$hiraZ, $hiraZ.$kataZ, 'R', $hiraTRE);
564             my $hi2ka = trclosure($hiraZ, $kataZ, 'R', $hiraTRE);
565             my $ka2hi = trclosure($kataZ, $hiraZ, 'R', $hiraTRE);
566              
567 23     23 1 7111 sub kataH2Z ($) { &$kataH2Z(@_) }
568 38     38 1 11142 sub kanaH2Z ($) { &$kataH2Z(@_) }
569 21     21 1 6686 sub hiraH2Z ($) { &$hiraH2Z(@_) }
570 22     22 1 5701 sub kataZ2H ($) { &$kataZ2H(@_) }
571 29     29 1 9097 sub kanaZ2H ($) { &$kanaZ2H(@_) }
572 19     19 1 5850 sub hiraZ2H ($) { &$hiraZ2H(@_) }
573 24     24 1 6739 sub hiXka ($) { &$hiXka(@_) }
574 19     19 1 4802 sub hi2ka ($) { &$hi2ka(@_) }
575 19     19 1 4684 sub ka2hi ($) { &$ka2hi(@_) }
576              
577              
578             ##
579             ## strsplit
580             ##
581             sub strsplit ($$;$) {
582 255     255 1 7764 my $strpat = shift;
583 255         337 my $str = shift;
584 255   100     588 my $lim = shift || 0;
585              
586 255 100       735 return wantarray ? () : 0 if $str eq '';
    100          
587              
588 153         136 my($pat);
589 153 100       271 if (!defined $strpat) {
590 34 100       88 if ($lim <= 0) {
591 12         14 return @{ [ split ' ', spaceZ2H($str), $lim ] };
  12         30  
592             }
593 22         106 $str =~ s/^(?:[ \n\r\t\f]|\x81\x40)+//;
594 22         38 $pat = '(?:(?:[ \n\r\t\f]|\x81\x40)+)';
595             } else {
596 119 100 100     347 if ($strpat eq '' && $lim <= 0) {
597             return wantarray
598 4 100       142 ? ($str =~ /$Char/go, $lim < 0 ? '' : ())
    100          
599             : ($lim < 0) + &length($str);
600             }
601 115         174 $pat = quotemeta $strpat;
602             }
603              
604 137 100       276 return wantarray ? ($str) : 1 if $lim == 1;
    100          
605              
606 129         149 my $cnt = 0;
607 129 100       299 my @ret = CORE::length $pat ? ('') : ();
608              
609 129 100       231 if (CORE::length $pat) {
610 91   100     726 while (($lim <= 0 || $cnt < $lim) && CORE::length($str)) {
      100        
611 646 100       2504 if ($str =~ s/^$pat//) {
612 228         1402 $cnt = push @ret, '';
613             } else {
614 418 50       1387 croak("$PACKAGE Panic in strsplit") if $str !~ s/^($Char)//o;
615 418         2500 $ret[-1] .= $1;
616             }
617             }
618             } else {
619 38   66     145 while ($cnt < $lim && CORE::length($str)) {
620 418 50       1562 croak("$PACKAGE Panic in strsplit") unless $str =~ s/^($Char)//o;
621 418         1908 $cnt = push @ret, $1;
622             }
623             }
624 129 100       310 $ret[-1] .= $str if $str ne '';
625 129 100       228 if ($lim == 0) {
626 31   100     204 pop @ret while defined $ret[-1] && $ret[-1] eq '';
627             }
628 129         576 return @ret;
629             }
630              
631             ##
632             ## strxfrm
633             ##
634             sub strxfrm ($) {
635 91938     91938 1 198498 my $str = shift;
636 91938 100       367569 $str =~ s/($Char)/ CORE::length $1 > 1 ? $1 : "\0".$1 /ge;
  91986         307272  
637 91938         270479 return $str;
638             }
639              
640 11491 100   11491 1 78283 sub strcmp($$) { $_[0] eq $_[1] ? 0 : strxfrm($_[0]) cmp strxfrm($_[1]) }
641 7     7 1 841 sub strEQ ($$) { $_[0] eq $_[1] }
642 7     7 1 527 sub strNE ($$) { $_[0] ne $_[1] }
643 7 100   7 1 86 sub strLT ($$) { $_[0] eq $_[1] ? '' : strxfrm($_[0]) lt strxfrm($_[1]) }
644 11475 100   11475 1 59376 sub strLE ($$) { $_[0] eq $_[1] ? 1 : strxfrm($_[0]) le strxfrm($_[1]) }
645 6 100   6 1 60 sub strGT ($$) { $_[0] eq $_[1] ? '' : strxfrm($_[0]) gt strxfrm($_[1]) }
646 4 100   4 1 40 sub strGE ($$) { $_[0] eq $_[1] ? 1 : strxfrm($_[0]) ge strxfrm($_[1]) }
647              
648             1;
649              
650             __END__