File Coverage

blib/lib/Regexp/SQL/LIKE.pm
Criterion Covered Total %
statement 38 38 100.0
branch 16 16 100.0
condition 3 3 100.0
subroutine 7 7 100.0
pod 1 1 100.0
total 65 65 100.0


line stmt bran cond sub pod time code
1             #
2             # This file is part of Regexp-SQL-LIKE
3             #
4             # This software is Copyright (c) 2011 by David Golden.
5             #
6             # This is free software, licensed under:
7             #
8             # The Apache License, Version 2.0, January 2004
9             #
10 1     1   25378 use 5.010;
  1         3  
  1         45  
11 1     1   6 use strict;
  1         2  
  1         49  
12 1     1   5 use warnings;
  1         3  
  1         55  
13              
14             package Regexp::SQL::LIKE;
15             BEGIN {
16 1     1   20 $Regexp::SQL::LIKE::VERSION = '0.001';
17             }
18             # ABSTRACT: Translate SQL LIKE pattern to a regular expression
19              
20             # Dependencies
21 1     1   1850 use autodie 2.00;
  1         20935  
  1         8  
22             use Sub::Exporter
23 1     1   13951 -setup => { exports => [ qw/to_regexp/ ] };
  1         15193  
  1         10  
24              
25              
26             sub to_regexp {
27 16     16 1 9184 my ($like) = @_;
28 16         30 my $re = '';
29              
30 16         82 my %anchors = (
31             start => substr($like, 0,1) ne '%',
32             end => substr($like,-1,1) ne '%',
33             );
34              
35             # split out tokens with backslashes before wildcards so
36             # we can figure out what is actually being escaped
37 16         175 my @parts = split qr{(\\*[.%])}, $like;
38              
39 16         47 for my $p ( @parts ) {
40 50 100       109 next unless length $p;
41 44         134 my $backslash_count =()= $p =~ m{(\\)}g;
42 44         114 my $wild_count =()= $p =~ m{([%.])}g;
43 44 100       98 if ($wild_count) {
44 18 100 100     76 if ( $backslash_count && $backslash_count % 2 ) {
    100          
45             # odd slash count, so wild card is escaped
46 5         13 my $last = substr( $p, -2, 2, '');
47 5         11 $p =~ s{\\\\}{\\};
48 5         15 $re .= quotemeta( $p . substr($last, -1, 1) );
49             }
50             elsif ( $backslash_count ) {
51             # even slash count, they only escape themselves
52 2         7 my $last = substr( $p, -1, 1, '');
53 2         7 $p =~ s{\\\\}{\\};
54 2 100       12 $re .= quotemeta( $p ) . ( $last eq '%' ? '.*' : '.' );
55             }
56             else { # just a wildcard, no escaping
57 11 100       37 $re .= $p eq '%' ? '.*' : '.';
58             }
59             }
60             else {
61             # no wildcards so apply any escapes freely
62 26         43 $p =~ s{\\(.)}{$1}g;
63 26         70 $re .= quotemeta( $p );
64             }
65             }
66              
67 16 100       53 substr( $re, 0, 0, '^' ) if $anchors{start};
68 16 100       45 $re .= '$' if $anchors{end};
69              
70 16         329 return qr/$re/;
71             }
72              
73             1;
74              
75              
76              
77             =pod
78              
79             =head1 NAME
80              
81             Regexp::SQL::LIKE - Translate SQL LIKE pattern to a regular expression
82              
83             =head1 VERSION
84              
85             version 0.001
86              
87             =head1 SYNOPSIS
88              
89             use Regexp::SQL::LIKE 'to_regexp';
90            
91             my $re = to_regexp( "Hello %" ); # returns qr/^Hello .*/
92              
93             =head1 DESCRIPTION
94              
95             This module converts an SQL LIKE pattern to its Perl regular expression
96             equivalent.
97              
98             Currently, only C<<< % >>> and C<<< . >>> wildcards are supported and only C<<< \ >>> is
99             supported as an escape character.
100              
101             No functions are exported by default. You may rename a function on import as
102             follows:
103              
104             use Regexp::SQL::Like to_regexp => { -as => 'regexp_from_like' };
105              
106             See L for more details on import customization.
107              
108             =head1 FUNCTIONS
109              
110             =head2 to_regexp
111              
112             my $re = to_regexp( "Hello %" );
113              
114             This function converts an SQL LIKE pattern into an equivalent regular
115             expression. A C<%> character matches any number of characters like C<.*> and a
116             C<.> character matchs a single character. Backspaces may be used to escape
117             C<%>, C<.> and C<\> itself:
118              
119             to_regexp( "Match literal \%" );
120              
121             All other characters are run through C to sanitize them.
122              
123             The function returns a compiled regular expression.
124              
125             =for Pod::Coverage method_names_here
126              
127             =for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders
128              
129             =head1 SUPPORT
130              
131             =head2 Bugs / Feature Requests
132              
133             Please report any bugs or feature requests by email to C, or through
134             the web interface at L. You will be automatically notified of any
135             progress on the request by the system.
136              
137             =head2 Source Code
138              
139             This is open source software. The code repository is available for
140             public review and contribution under the terms of the license.
141              
142             L
143              
144             git clone http://github.com/dagolden/regexp-sql-like
145              
146             =head1 AUTHOR
147              
148             David Golden
149              
150             =head1 COPYRIGHT AND LICENSE
151              
152             This software is Copyright (c) 2011 by David Golden.
153              
154             This is free software, licensed under:
155              
156             The Apache License, Version 2.0, January 2004
157              
158             =cut
159              
160              
161             __END__