Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change

Re: better way to escape escapes

by kcott (Chancellor)
on Apr 16, 2014 at 03:00 UTC ( #1082417=note: print w/replies, xml ) Need Help??

in reply to better way to escape escapes

G'day RonW,

The first thing to do, to make your code more readable and maintainable, is to assign those regex fragments with the escapes to meaningful named variables.

An '@' character doesn't need to be escaped in a character class, so you can start with something like:

my $any_slash_or_at = qr{ [\\@] }x;

In my code below, you'll see that having done that means the rest of the code has almost no backslashes at all. This hopefully makes the code a lot more readable now and, six months or more down the track, when you or someone else needs to make a change.

I then started to build up more complex regexes based on $any_slash_or_at. Again, this helps with readability and future maintenance.

I ran a test, replacing your

s/(?<![\\\@])[\\\@]\@/\x11/g; s/(?<![\\\@])[\\\@]\\/\x12/g;


s/$slash_or_at__at/DC1/g; s/$slash_or_at__slash/DC2/g;

The ouput looks fine: I'll leave you to make similar changes in the while loop.

You asked about "a better way". Building up the regex from fragments hopefully goes some way towards this. I've provided an alternative which uses a less complex regex (although still built from the initial $any_slash_or_at fragment) and requires only a single substitution: if nothing else, that gives you another option.

[Everything I've provided should work with Perl v5.8 — there may be better solutions if you have a more recent Perl version. As I didn't know what version you're working with, I didn't persue these other potential solutions.]

Here's the test script:

#!/usr/bin/env perl -l use strict; use warnings; my $test_string = '\\\\\\ \\\\@ \\@\\ \\@@ @\\\\ @\\@ @@\\ @@@ \\\\ \\@ @\\ @@ \\ +@'; my $any_slash_or_at = qr{ [\\@] }x; my $lone_slash_or_at = qr{ (?<!$any_slash_or_at) $any_slash_or_at }x; my $slash_or_at__at = qr{ $lone_slash_or_at \@ }x; my $slash_or_at__slash = qr{ $lone_slash_or_at \\ }x; # Your code - a lot easier to read print 'Testing your code:'; $_ = $test_string; print; s/$slash_or_at__at/DC1/g; s/$slash_or_at__slash/DC2/g; print; # An alternative with a less complex regex and a single substitution my %replace = ( '@' => 'DC1', '\\' => 'DC2' ); my $escape_slash_or_at = qr{ $any_slash_or_at ( $any_slash_or_at ) }x; print 'Testing simultaneous replacements:'; $_ = $test_string; print; s/$escape_slash_or_at/$replace{$1}/g; print;


Testing your code: \\\ \\@ \@\ \@@ @\\ @\@ @@\ @@@ \\ \@ @\ @@ \ @ DC2\ DC2@ DC1\ DC1@ DC2\ DC2@ DC1\ DC1@ DC2 DC1 DC2 DC1 \ @ Testing simultaneous replacements: \\\ \\@ \@\ \@@ @\\ @\@ @@\ @@@ \\ \@ @\ @@ \ @ DC2\ DC2@ DC1\ DC1@ DC2\ DC2@ DC1\ DC1@ DC2 DC1 DC2 DC1 \ @

-- Ken

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1082417]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (2)
As of 2018-02-22 00:53 GMT
Find Nodes?
    Voting Booth?
    When it is dark outside I am happiest to see ...

    Results (288 votes). Check out past polls.