File Coverage

blib/lib/Regexp/Result.pm
Criterion Covered Total %
statement 51 61 83.6
branch 1 6 16.6
condition n/a
subroutine 14 21 66.6
pod 4 6 66.6
total 70 94 74.4


line stmt bran cond sub pod time code
1             package Regexp::Result;
2 1     1   22293 use strict;
  1         2  
  1         35  
3 1     1   5 use warnings;
  1         1  
  1         27  
4 1     1   975 use Moo;
  1         19510  
  1         11  
5 1     1   1868 use 5.010; # we require ${^MATCH} etc
  1         4  
  1         50  
6             our $VERSION = '0.003';
7 1     1   7 use Sub::Name 'subname';
  1         1  
  1         109  
8              
9             =head1 NAME
10              
11             Regexp::Result - store information about a regexp match for later retrieval
12              
13             =head1 SYNOPSIS
14              
15             $foo =~ /(a|an|the) (\w+)/;
16             my $result = Regexp::Result->new();
17              
18             # ...
19             # some other code which potentially executes a regular expression
20              
21             my $determiner = $result->c(1);
22             # i.e. $1 at the time when the object was created
23              
24             Have you ever wanted to retain information about a regular expression
25             match, without having to go through the palaver of pulling things out
26             of C<$1>, C, etc. and assigning them each to temporary variables
27             until you've decided what to use them as?
28              
29             Regexp::Result objects, when created, contain as much information about
30             a match as perl can tell you. This means that you just need to create
31             one variable and keep it.
32              
33             Hopefully, your code will be more comprehensible when it looks like
34             C<< $result->last_numbered_match_start->[-1] >>,
35             instead of C<$-[-1]>. The documentation for the punctuation
36             variables, by the way, is hidden away in C
37             along with scary things like C<^H>. I've copied most of it and/or
38             rewritten it below.
39              
40             =head1 METHODS
41              
42             =head3 new
43              
44             Creates a new Regexp::Result object. The object will gather data from
45             the last match (if successful) and store it for later retrieval.
46              
47             Note that almost all of the contents are read-only.
48              
49             =cut
50              
51             =head3 numbered_captures
52              
53             This accesses C<$1>, C<$2>, etc as C<< $rr->numbered_captures->[0] >>
54             etc. Note the numbering difference!
55              
56             =cut
57              
58             has numbered_captures=>
59             is => 'ro',
60             default => sub{
61             my $captures = [];
62 1     1   6 no strict 'refs';
  1         2  
  1         63  
63             for my $i (1..$#-) { #~ i.e until the end of LAST_MATCH_START
64             push @$captures, ${$i};
65             }
66 1     1   5 use strict 'refs';
  1         2  
  1         242  
67             $captures;
68             };
69              
70             =head3 c
71              
72             This accesses the contents of C, but uses numbers from 1
73             for comparability with C<$1>, C<$2>, C<$3>, etc.
74              
75             =cut
76              
77             sub c {
78 5     5 1 26 my ($self, $number) = @_;
79 5 50       16 if ($number) {
80             #:todo: consider allowing more than one number
81 5         36 return $self->numbered_captures->[$number - 1];
82             }
83 0         0 return undef;
84             }
85              
86             sub _has_scalar {
87 7     7   15 my ($name, $creator) = @_;
88 7         23 has $name =>
89             is => 'ro',
90             default => $creator
91             }
92              
93             #~ _has_array
94             #~
95             #~ _has_array primes => sub { [2,3,5,7,11] };
96             #~ $object->primes->[0]; # 2
97             #~ $object->primes(0); # also 2
98              
99             sub _has_array {
100 2     2   5 my ($name, $creator) = @_;
101 2         5 my $realName = '_'.$name;
102 2         9 has $realName =>
103             is => 'ro',
104             default => $creator;
105             my $accessor = sub {
106 0     0 1 0 my $self = shift;
        0 1    
        0      
107 0 0       0 if (@_) {
108             #~ ideally check if @_ contains only numbers
109             #~ Should foo(1,3) return something different?
110 0         0 return $self->$realName->[@_];
111             }
112             else {
113 0         0 return $self->$realName;
114             }
115 2         621 };
116             {
117 2         3 my $package = __PACKAGE__;
  2         4  
118 1     1   6 no strict 'refs';
  1         1  
  1         186  
119 2         5 my $fullName = $package . '::' . $name;
120 2         18 *$fullName = subname( $name, $accessor );
121             }
122             }
123              
124             sub _has_hash {
125 2     2   4 my ($name, $creator) = @_;
126 2         4 my $realName = '_'.$name;
127 2         6 has $realName =>
128             is => 'ro',
129             default => $creator;
130             my $accessor = sub {
131 0     0 0 0 my $self = shift;
        0 0    
        0      
132 0 0       0 if (@_) {
133 0         0 return $self->$realName->{@_};
134             }
135             else {
136 0         0 return $self->$realName;
137             }
138 2         412 };
139             {
140 2         3 my $package = __PACKAGE__;
  2         3  
141 1     1   4 no strict 'refs';
  1         2  
  1         318  
142 2         4 my $fullName = $package . '::' . $name;
143 2         19 *$fullName = subname( $name, $accessor );
144             }
145             }
146              
147             =head3 match, prematch, postmatch
148              
149             'The quick brown fox' =~ /q[\w]+/p;
150             my $rr = Regexp::Result->new();
151             print $rr->match; # prints 'quick'
152             print $rr->prematch; # prints 'The '
153             print $rr->postmatch; # prints ' brown fox'
154              
155             When a regexp is executed with the C

flag, the variables
156             C<${^MATCH}>, C<${^PREMATCH}>, and C<${^POSTMATCH}> are set.
157             These correspond to the entire text matched by the regular expression,
158             the text in the string which preceded the matched text, and the text in
159             the string which followed it.
160              
161             The C method provides access to the data in C<${^MATCH}>.
162              
163             The C method provides access to the data in C<${^PREMATCH}>.
164              
165             The C method provides access to the data in C<${^POSTMATCH}>.
166              
167             Note: no accessor is provided for C<$&>, C<$`>, and C<$'>, because:
168              
169             a) The author feels they are unnecessary since perl 5.10 introduced
170             C<${^MATCH}> etc.
171              
172             b) Implementing accessors for them would force a performance penalty
173             on everyone who uses this module, even if they don't have any need of
174             C<$&>.
175              
176             =cut
177              
178             _has_scalar match => sub{
179             ${^MATCH}
180             };
181              
182             _has_scalar prematch => sub{
183             ${^PREMATCH}
184             };
185              
186             _has_scalar postmatch => sub{
187             ${^POSTMATCH}
188             };
189             =head3 last_paren_match
190              
191             Equivalent to C<$+>.
192              
193             The text matched by the last capturing parentheses of the match.
194             This is useful if you don't know which one of a set of
195             alternative patterns matched. For example, in:
196              
197             /Version: (.*)|Revision: (.*)/
198              
199             C stores either the version or revision (whichever
200             exists); perl would number these C<$1> and C<$2>.
201              
202             =cut
203              
204             _has_scalar last_paren_match => sub{
205             $+;
206             };
207              
208             =head3 last_submatch_result
209              
210             Equivalent to C<$^N>.
211              
212             =cut
213              
214             _has_scalar last_submatch_result => sub{
215             $^N;
216             };
217              
218             =head3 last_numbered_match_end
219              
220             Equivalent to C<@+>.
221              
222             This array holds the offsets of the ends of the last successful
223             submatches in the currently active dynamic scope. C<$+[0]> is the
224             offset into the string of the end of the entire match. This is the
225             same value as what the C function returns when called on the
226             variable that was matched against. The nth element of this array
227             holds the offset of the nth submatch, so C<$+[1]> is the offset past
228             where C<$1> ends, C<$+[2]> the offset past where C<$2> ends, and so
229             on.
230              
231             =cut
232              
233             _has_array last_numbered_match_end => sub{
234             [@+]
235             };
236              
237             =head3 last_numbered_match_start
238              
239             Equivalent to C<@->.
240              
241             This array holds the offsets of the starts of the last successful
242             submatches in the currently active dynamic scope. C<$-[0]> is the
243             offset into the string of the start of the entire match. The nth
244             element of this array holds the offset of the nth submatch, so
245             C<$-[1]> is the offset where C<$1> starts, C<$-[2]> the offset
246             where C<$2> starts, and so on.
247              
248             =cut
249              
250             _has_array last_numbered_match_start => sub{
251             [@-]
252             };
253             =head3 named_paren_matches
254              
255             'wxyz' =~ /(?w)(?x)(?y)(?z)/
256              
257             # named_paren_matches is now:
258             #
259             # {
260             # EVEN => [ 'x', 'z' ],
261             # ODD => [ 'w', 'y' ]
262             # }
263              
264             Equivalent to C<%->.
265              
266             This variable allows access to the named capture
267             groups in the last successful match in the currently active
268             dynamic scope. To each capture group name found in the regular
269             expression, it associates a reference to an array containing the
270             list of values captured by all buffers with that name (should
271             there be several of them), in the order where they appear.
272              
273             =cut
274              
275             _has_hash named_paren_matches => sub{
276 1     1   905 {%-}
  1         521  
  1         168  
277             };
278              
279             =head3 last_named_paren_matches
280              
281             'wxyz' =~ /(?w)(?x)(?y)(?z)/
282              
283             # last_named_paren_matches is now:
284             #
285             # {
286             # EVEN => 'x',
287             # ODD => 'w',
288             # }
289              
290             The "%+" hash allows access to the named capture
291             buffers, should they exist, in the last successful match in the
292             currently active dynamic scope.
293              
294             The keys of the "%+" hash list only the names of buffers that have
295             captured (and that are thus associated to defined values).
296              
297             Note: C<%-> and C<%+> are tied views into a common internal hash
298             associated with the last successful regular expression. Therefore
299             mixing iterative access to them via C may have unpredictable
300             results. Likewise, if the last successful match changes, then the
301             results may be surprising.
302              
303             Author's note: I have no idea why this is a useful thing to use.
304             But perl provides it, and it is occasionally used according to
305             L (461 distros, of which some the string
306             C<\%\+|\$\+\{> is in a binary stream).
307              
308             =cut
309              
310             _has_hash last_named_paren_match => sub{
311             {%+}
312             };
313              
314             =head3 last_regexp_code_result
315              
316             The result of evaluation of the last successful C<(?{ code })>
317             regular expression assertion (see L).
318              
319             =cut
320              
321             _has_scalar last_regexp_code_result => sub{
322             $^R;
323             };
324              
325             =head3 re_debug_flags
326              
327             The current value of the regex debugging flags. Set to 0 for no
328             debug output even when the C module is loaded. See
329             L for details.
330              
331             =cut
332              
333             _has_scalar re_debug_flags => sub{
334             ${^RE_DEBUG_FLAGS}
335             };
336              
337             =head3 pos
338              
339             Returns the end of the match. Equivalent to C<$+[0]>.
340              
341             =cut
342              
343             sub pos {
344 0     0 1   return shift->last_match_end->[0];
345             }
346              
347             =head1 BUGS
348              
349             Please report any bugs or feature requests to the github issues tracker at L. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
350              
351             =head1 AUTHORS
352              
353             Daniel Perrett
354              
355             =head1 LICENSE AND COPYRIGHT
356              
357             Copyright 2012-2013 Daniel Perrett.
358              
359             This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.
360              
361             See L for more information.
362              
363              
364             =cut
365              
366             1;
367