stackErr
stackErr

Reputation: 4170

Escaping wildcard file paths perl

I have an array of files:

my @plistFiles = glob('Logs/*/*.plist');

which I need to escape, that will contain '(' and ')' as well as the usual spaces.

Here is one of the file paths @plistFiles will return:

Logs/Run 1 (13)/Automation Results.plist

I currently have this code for escaping spaces in file paths which I pass to a command in the Terminal in OSX:

$plistFile =~ s/\ /\\\ /g;

So how can I edit this regex to also escape ( and )?

Would this be correct just for escaping ( and )?:

$plistFile =~ s/\(\d)/\\\(\d\\\)/g;

Upvotes: 0

Views: 1266

Answers (4)

Ωmega
Ωmega

Reputation: 43683

Using regex you can add escape slashes with

s/[() ]/\\$&/g;

See this demo.

or

s/(?=[() ])/\\/g;

See this demo.

Upvotes: 1

Borodin
Borodin

Reputation: 126742

I can't see why a call to quotemeta won't suffice. Yes it will also escape the slashes and dots, but that shouldn't matter.

However it is also simple to escape just whitespace and parentheses.

This program show both techniques

use strict;
use warnings;

use feature 'say';

my $path = 'Logs/Run 1 (13)/Automation Results.plist';
my $escaped = quotemeta $path;
say $escaped;

$escaped = $path =~ s/([\s()])/\\$1/gr;
say $escaped;

output

Logs\/Run\ 1\ \(13\)\/Automation\ Results\.plist

Logs/Run\ 1\ \(13\)/Automation\ Results.plist

Upvotes: 1

ruakh
ruakh

Reputation: 183466

To convert e.g. (13) to \(13\), you could write:

$plistFile =~ s/ /\\ /g;
$plistFile =~ s/\((\d+)\)/\\($1\\)/g;

But I think you're probably better off just escaping all instances of ( and ), whether or not they surround numbers:

$plistFile =~ s/([ ()])/\\$1/g;

Upvotes: -1

Charlie
Charlie

Reputation: 76

You'll find it easier to use {} to delimit your regex. Saves some \ eye wobbliness.

#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use 5.10.0;
use Data::Dumper;

my $to_match = "( this dreadful ) filename";
$to_match =~ s{([\(\)])}{\\$1}g;
say $to_match;

This does this:

$ perl x.pl
\( this dreadful \) filename

If you need to escape spaces as well as ()s then

$to_match =~ s{([\(\s\)])}{\\$1}g;

Upvotes: 0

Related Questions