It may look ugly, but
my $quoted = qr/'[^']+'/; # ' fix Stackoverflow highlighting my %_extract_wanted_cache; sub extract_wanted_memo { my($string, $index) = @_; $string =~ ($_extract_wanted_cache{$index} ||= qr/^(?:.*?$quoted.*?){@{[$index-1]}}($quoted)/) ? $1 : (); }
Benchmarking suggests that this may be useful:
sub extract_wanted { my($string, $index) = @_; $string =~ /^(?:.*?$quoted.*?){@{[$index-1]}}($quoted)/ ? $1 : (); } sub extract_wanted_gindex { my($string, $index) = @_; ($string =~ /$quoted/g)[$index-1]; } use Benchmark; timethese -1 => { nocache => sub { extract_wanted $string2, 3 }, memoize => sub { extract_wanted_memo $string2, 3 }, index => sub { extract_wanted_gindex $string2, 3 }, nocache_fail => sub { extract_wanted $string2, 100 }, memoize_fail => sub { extract_wanted_memo $string2, 100 }, index_fail => sub { extract_wanted_gindex $string2, 100 }, }
Results:
Benchmark:
running
index, index_fail, memoize, memoize_fail, nocache, nocache_fail
for at least 1 CPU seconds
...
index: 1 w / c secs (1.04 usr + 0.00 sys = 1.04 CPU) @ 183794.23 / s (n = 191146)
index_fail: 1 w / c secs (1.03 usr + 0.00 sys = 1.03 CPU) @ 185578.64 / s (n = 191146)
memoize: 1 w / c secs (1.00 usr + 0.00 sys = 1.00 CPU) @ 264664.00 / s (n = 264664)
memoize_fail: 0 w / c secs (1.03 usr + 0.00 sys = 1.03 CPU) @ 835106.80 / s (n = 860160)
nocache: 0 w / c secs (1.03 usr + 0.00 sys = 1.03 CPU) @ 196495.15 / s (n = 202390)
nocache_fail: 2 w / c secs (1.03 usr + 0.00 sys = 1.03 CPU) @ 445390.29 / s (n = 458752) source share