简体   繁体   中英

How to split a string by \ in perl?

use Data::Dumper qw(Dumper);

@arr=split('\/',"\Program Files\Microsoft VisualStudio\VC98\Bin\Rebase.exe");

print(Dumper \@arr);

output:

$VAR1 = [     

'Program FilesMicrosoft VisualStudioVC98BinRebase.exe'

];

Required output:

$VAR1 = [     
'Program Files',

'Microsoft VisualStudio',

'VC98',

'Bin',

'Rebase.exe'
];

You are splitting on the forward slash / (escaped by \\ ), while you clearly need the \\ .

Since \\ itself escapes things, you need to escape it, too

use warnings;
use strict;
use feature 'say';

my $str = '\Program Files\Microsoft VisualStudio\VC98\Bin\Rebase.exe';

my @ary = split /\\/, $str;

shift @ary if $ary[0] eq '';

say for @ary;

what prints the path components, one per line.

Since this string begins with a \\ the first element of @ary is going to be an empty string, as that precedes the first \\ . We remove it from the array by shift , with a check.

Note that for this string one must use '' , or the operator form q(...) , since the double quotes try to interpolate the presumed escapes \\P , \\M (etc) in the string, failing with a warning. It is a good idea to use '' for literal strings and "" (or qq() ) when you need to interpolate variables.

Another way to do this is with regex

my @ary = $str =~ /[^\\]+/g;

The negated character class , [^...] , with the (escaped) \\ matches any character that is not \\ . The quantifier + means that at least one such match is needed while it matches as many times as possible. Thus this matches a sequence of characters up to the first \\ .

With the modifier /g the matching keeps going through the string to find all such patterns.

Assigning to an array puts the match operator in list context , in which the list of matches is returned, and assigned to @ary . In a scalar context only the true (1) or false (empty string) is returned.

No capturing () are needed here, since we want everything that is matched. Generally the () in list context are needed so that only the captured matches are returned.

With this we don't have to worry about an empty string at the beginning since there is no match before the first \\ , as there are no characters before it while we requested at least one non- \\ .


But working with paths is common and there are ready tools for that, which take care of details. The core module File::Spec is multi-platform and its splitdir breaks the path into components

use File::Spec;

my @path_components = File::Spec->splitdir($str);

The first element is again an empty string if the path starts with \\ (or / on Unix/Mac).

Thanks to Sinan Ünür for a comment.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM