my $s = "abcdefghi"; my @a = ([ 0, 3 ], [ 0, 1 ], [ 1, 2 ], [ 2, 1 ]); my $qr = matcher(\@a); match($s, $qr); sub matcher { my $array = shift; my(%pos, @undef); my($start, $length) = @{ $array->[0] }; for (1 .. $#$array) { my($pos, $width) = ($array->[$_][0], $array->[$_][1]); if (defined $pos) { $pos{$pos} .= '('; $pos{$pos + $width} .= ')'; } else { push @undef, $_; } } my $qr = '.' x ($start + $length); for (sort { $b <=> $a } keys %pos) { substr $qr, $_, 0, $pos{$_}; } for (reverse @undef) { $qr =~ s/((.*?\(){$_})/$1((?!))?/; } $qr =~ s{(.{$start})}{(?<=^$1)} if $start; qr/$qr/; }