http://www.perlmonks.org?node_id=237825


in reply to Regex matching on anywhere but the beginning or end of a line

Well, you can achieve that without regexp:

my $string = q{"string (12" or 1 foot or 1') into 6" MySQL varchar"}; local $_ = 1; while( ($_ = index($string,'"',$_)) !=-1 and ++$_ < length($string) ){ substr($string,$_++,0,'"'); }
--
http://fruiture.de

Replies are listed 'Best First'.
Re: Re: Regex matching on anywhere but the beginning or end of a line
by xmath (Hermit) on Feb 23, 2003 at 10:10 UTC
    But why would you want to do that? Regexes are one of perl's major strengths, and they can deal with this situation very nicely.

    Your code snippet (idx) also seems to be slower than both regex-based solutions given above (zwa, sub):

    Rate idx sub zwa idx 73430/s -- -5% -15% sub 77672/s 6% -- -10% zwa 86374/s 18% 11% --
    (Benchmarked the same way as this one)

      Although I agree that probably a regexp is more straight-forward, I get different results benchmarking the stuff.

      my $string = q{"string (12" or 1 foot or 1') into 6" MySQL varchar"}; benchmark( shift, q{"string (12"" or 1 foot or 1') into 6"" MySQL varchar"}, 'substr' => sub { my $t = $string; substr($t, 1, -1) =~ s/"/""/g; $t }, 's///' => sub { my $t = $string; $t =~ s/(?<=.)"(?=.)/""/g; $t }, 'index' => sub { my $t = $string; local $_ = 1; while( ($_ = index($t,'"',$_)) !=-1 and ++$_ < length($t) ){ substr($t,$_++,0,'"'); } $t }, );

      benchmark() is just a wrapper around Benchmark::cmpthese() that checks the results of the routines.

      # run with perl 5.6.1 EXPECTED : "string (12"" or 1 foot or 1') into 6"" MySQL varchar" index : "string (12"" or 1 foot or 1') into 6"" MySQL varchar" s/// : "string (12"" or 1 foot or 1') into 6"" MySQL varchar" substr : "string (12"" or 1 foot or 1') into 6"" MySQL varchar" Benchmark: timing 1000000 iterations of index , s/// , subs +tr ... index : 19 wallclock secs (19.66 usr + 0.02 sys = 19.68 CPU) @ 5 +0813.01/s (n=1000000) s/// : 19 wallclock secs (19.85 usr + 0.00 sys = 19.85 CPU) @ 5 +0377.83/s (n=1000000) substr : 23 wallclock secs (24.13 usr + 0.00 sys = 24.13 CPU) @ 4 +1442.19/s (n=1000000) Rate substr s/// index substr 41442/s -- -18% -18% s/// 50378/s 22% -- -1% index 50813/s 23% 1% -- # and with perl 5.8.0 EXPECTED : "string (12"" or 1 foot or 1') into 6"" MySQL varchar" substr : "string (12"" or 1 foot or 1') into 6"" MySQL varchar" index : "string (12"" or 1 foot or 1') into 6"" MySQL varchar" s/// : "string (12"" or 1 foot or 1') into 6"" MySQL varchar" Benchmark: timing 1000000 iterations of index , s/// , subs +tr ... index : 18 wallclock secs (18.71 usr + 0.01 sys = 18.72 CPU) @ 5 +3418.80/s (n=1000000) s/// : 33 wallclock secs (31.67 usr + 0.02 sys = 31.69 CPU) @ 3 +1555.70/s (n=1000000) substr : 35 wallclock secs (35.24 usr + 0.01 sys = 35.25 CPU) @ 2 +8368.79/s (n=1000000) Rate substr s/// index substr 28369/s -- -10% -47% s/// 31556/s 11% -- -41% index 53419/s 88% 69% --
      --
      http://fruiture.de
        Okay, I re-ran the benchmark with your exact code on my computer, and I got: