Reputation: 107
I was trying to reverse a motif which is like a regular expression.
An example of my motif : TA[TC]AA
When I use the function (reverse) it reverses the [
into a ]
, so I obtained something like : AA]CT[AT
and I want something like AA[CT]AT
.
What can I do for it?
Thank you so much for your help!!
Upvotes: 3
Views: 1044
Reputation: 57600
You cannot reverse all Perl regular expressions. But in this simple case where you only have literal characters or simple character classes, you could use an approach where you disassemble the regex atom by atom, then reverse the list of atoms. Here, an atom would be any regex thingy that matches independently, e.g. a literal character or a charclass.
sub reverse_pattern {
my ($pattern) = @_;
my @atoms;
while (length $pattern) {
# parse a literal (here, we just match letters)
if ($pattern =~ s/^(\w)//) {
push @atoms, $1;
}
# parse a charclass: \[ ... \]
# the inside of a charclass is anything except "]" or "\": [^\]\\]+
elsif ($pattern =~ s/^(\[[^\]\\]+\])//) {
push @atoms, $1;
}
else {
die "Unsupported pattern syntax: $pattern";
}
}
return join '' => reverse @atoms;
}
use Test::More;
is reverse_pattern('TA[TC]AA'), 'AA[TC]AT';
done_testing;
Upvotes: 3
Reputation: 241858
If the square brackets are the only problem, use transliteration to switch them:
#! /usr/bin/perl
use warnings;
use strict;
use Syntax::Construct qw{ /r };
use Test::More tests => 1;
my $motif = 'TA[TC]AA';
my $reversed = 'AA[CT]AT';
is reverse($motif =~ tr/[]/][/r), $reversed;
Or, in pre-5.14 where /r
isn't available:
my $r = reverse $motif;
$r =~ tr/[]/][/;
Upvotes: 5