in reply to how to speed up that dynamic regex?
Hello rsFalse,
First, the code you have does not appear to be producing correct results. For example, you have this line of input:
()(())()
which produces:
8 1
but by inspection we can see that the longest subsequence of validly-nested parentheses is (()) which is only 4 characters long.
Second, as Eily says you can get a significant speedup by using (?PARNO). For example, adapting the code in Can-I-use-Perl-regular-expressions-to-match-balanced-text of perlfaq6, I came up with this:
use strict; use warnings; use List::Util 'max'; srand; my @lines = <DATA>; my $n = 1000; my $long = ''; $long .= qw{( )}[ int(rand() * 2) ] for 1 .. $n; my $regex = qr{ ( # start of capture group 1 \( # match an opening parenthesis (?: [^()]++ # one or more non-parentheses, non backtra +cking | # OR (?1) # recurse to capture group 1 )* \) # match a closing parenthesis ) # end of capture group 1 }x; for my $string (@lines, $long) { my $max = 0; my $occ = 1; my @groups = $string =~ m/$regex/g; if (@groups) { @groups = sort { length $a <=> length $b } @groups; $max = length $groups[-1]; for my $i (reverse 0 .. $#groups - 1) { if (length $groups[$i] == length $groups[-1]) { ++$occ; } else { last; } } } print "$max $occ\n"; } __DATA__ )((())))(()()) ))( ()(())() ((((()((( (()())()(())()()())())()((()(()(())()()())((()(())()(()()()()))()(())( +)(((()())()(()((())()(())(()))
Typical output:
23:28 >perl 1071_SoPW.pl 6 2 0 1 4 1 2 1 20 1 266 1 23:28 >
For a long string this is much faster than using (??{ code }).
Hope that helps,
| Athanasius <°(((>< contra mundum | Iustus alius egestas vitae, eros Piratica, |
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: how to speed up that dynamic regex?
by AnomalousMonk (Archbishop) on Nov 05, 2014 at 01:59 UTC | |
by rsFalse (Chaplain) on Nov 07, 2014 at 10:44 UTC | |
by rsFalse (Chaplain) on Nov 07, 2014 at 11:28 UTC | |
|
Re^2: how to speed up that dynamic regex?
by rsFalse (Chaplain) on Nov 04, 2014 at 23:45 UTC |