File Coverage

blib/lib/Regexp/Assemble/Compressed.pm
Criterion Covered Total %
statement 60 61 98.3
branch 28 32 87.5
condition 25 30 83.3
subroutine 5 5 100.0
pod 1 1 100.0
total 119 129 92.2


line stmt bran cond sub pod time code
1             package Regexp::Assemble::Compressed;
2              
3 2     2   11 use strict;
  2         4  
  2         87  
4 2     2   12 use warnings;
  2         2  
  2         100  
5             our $VERSION = '0.02';
6 2     2   11 use base qw(Regexp::Assemble);
  2         3  
  2         6971  
7              
8             # Note: maybe handle \U,\L more smartly
9             our $char = qr/
10             (?:\\u|\\l|) # \u, \l acts on one char or char group
11             (?:
12             \\Q.+?\\E # capture \Q..\E completely
13             | \[:[^:]+:\] # posix char class
14             | \\[UL].+?(?:\\E|\Z) # capture \U..\E and \L..\E completely
15             | \\x(?:\{[\dA-Fa-f]+\}|[\dA-Fa-f]{1,2}) # \x.. or \x{...}
16             | \\\d{1,3} # \000 - octal
17             | \\N\{[^{]+\} # unicode char
18             | \\[pP]\{[^{]+\} # unicode character class
19             | \\c. # control char \cX
20             | \\. # \t \n \s ...
21             | . # any char
22             )
23             /xo;
24              
25             sub as_string {
26 21     21 1 4740 my $self = shift;
27 21         209 my $string = $self->SUPER::as_string;
28 21         45561 $string =~ s{(?
  21         78  
29 21         136 return $string;
30             }
31              
32             sub _compress {
33 21     21   42 my $string = shift;
34 21         1169 my @characters = sort $string =~ m{ ( $char\-$char | $char ) }sgx;
35             #warn "[ ".join('|', @characters)." ]";
36 21         58 my @stack = ();
37 21         32 my @skipped = ();
38 21         24 my $last;
39 21         36 for my $char (@characters) {
40 122 100 100     354 if ( length($char) == 1 ) {
    100          
41 94         111 my $num = ord $char;
42 94 100 100     349 if (defined $last and $num - $last == 0) { next }
  2         4  
43 92 50 100     654 if (defined $last and @skipped and $num >= ord $skipped[0] and $num <= ord $skipped[-1]) { next }
  0   66     0  
      66        
44 92 100 100     697 if (defined $last and $num - $last == 1) {
    100          
45 84         123 push @skipped, $char;
46 84         84 $last = $num;
47 84         151 next;
48             }
49             elsif (@skipped) {
50 1 50       7 push @stack, @skipped < 2 ? @skipped : ('-', $skipped[-1]);
51 1         8 @skipped = ();
52             }
53 8         14 push @stack, $char;
54 8         15 $last = $num;
55             }
56             elsif (length $char == 3 and $char =~ /^([^\\])-([^\\])$/) {
57 18         53 my ($beg,$end) = ($1,$2);
58 18         29 my $num = ord $beg;
59 18         23 my $enn = ord $end;
60 18 100 66     122 if (defined $last and @skipped and $num + 1 >= ord $skipped[0] and $num <= ord $skipped[-1]) {
      66        
      66        
61 4 100       14 if ($enn <= ord $skipped[-1]) { next }
  3         10  
62             else {
63 1         2 my $next = $skipped[-1];
64 1         2 ++$next;
65 1         4 push @skipped, $next..$end;
66 1         2 $last = $enn;
67 1         3 next;
68             }
69             }
70 14 100 100     146 if (defined $last and $num - $last == 1) {
    100          
71 2         17 push @skipped, $beg..$end;
72 2         4 $last = $enn;
73 2         6 next;
74             }
75             elsif (@skipped) {
76 2 100       9 push @stack, @skipped < 2 ? @skipped : ('-', $skipped[-1]);
77 2         6 @skipped = ();
78             }
79 12         26 push @stack, $beg;
80 12         191 push @skipped, ++$beg..$end;
81 12         40 $last = $enn;
82             }
83             else {
84 10 100       23 if (@skipped) {
85 1 50       6 push @stack, @skipped < 2 ? @skipped : ('-', $skipped[-1]);
86 1         3 @skipped = ();
87             }
88 10         26 push @stack, $char;
89             }
90             }
91 21 100       56 if (@skipped) {
92 13 50       47 push @stack, @skipped < 2 ? @skipped : ('-', $skipped[-1]);
93             }
94 21         244 return join '', @stack;
95             }
96              
97             1;
98             __END__