Extracting part of strings?

K

Karlo Lozovina

Hi folks! Perl newbie in need of assistance :). I've got array
@dir_list, with bunch of entries like "/home/something/else" and I
want to extract the last part, that is "else".

I did it like this:

for($i = 0 ; $i <= $#dir_list ; $i++) {
@tmp_fields = split /\//, "$dir_list[$i]";
$dirnames[$i] = $tmp_fields[$#tmp_fields];
}

Since I'm an extreme Perl newbie (started learning it this afternoon
:>), I'm just wondering is there a better, or more standard way of
doing stuff like this?
 
J

Jürgen Exner

Karlo said:
Hi folks! Perl newbie in need of assistance :). I've got array
@dir_list, with bunch of entries like "/home/something/else" and I
want to extract the last part, that is "else".

I did it like this:

for($i = 0 ; $i <= $#dir_list ; $i++) {
@tmp_fields = split /\//, "$dir_list[$i]";
$dirnames[$i] = $tmp_fields[$#tmp_fields];
}

Since I'm an extreme Perl newbie (started learning it this afternoon

Yep, there is. The perlish way of doing it would be to use the function
basename() from the module File::Basename. Further information see 'perldoc
File::Basename'.

jue
 
K

Karlo Lozovina

Yep, there is. The perlish way of doing it would be to use the
function basename() from the module File::Basename. Further
information see 'perldoc File::Basename'.

Wow, wish I knew that an hour ago :). Thanks a lot, this will make my
life lot easier :).
 
A

Arndt Jonasson

Karlo Lozovina said:
Wow, wish I knew that an hour ago :). Thanks a lot, this will make my
life lot easier :).

For doing it with only Perl primitives, look up 'map' and regular
expressions.
 
J

Jürgen Exner

Arndt said:
For doing it with only Perl primitives, look up 'map' and regular
expressions.

Would be interesting to see how you parse file paths in a portable way using
only REs....

jue
 
A

Arndt Jonasson

Jürgen Exner said:
Would be interesting to see how you parse file paths in a portable way using
only REs....

If the key word is "portable", I would probably look for an existing
implementation of pathname-handling functions. Knowing about 'map'
and regular expressions is still interesting, if you want to write any
Perl code yourself.
 
P

Peter Wyzl

: Hi folks! Perl newbie in need of assistance :). I've got array
: @dir_list, with bunch of entries like "/home/something/else" and I
: want to extract the last part, that is "else".
:
: I did it like this:
:
: for($i = 0 ; $i <= $#dir_list ; $i++) {

This loops through all elements of the array @dir_list

: @tmp_fields = split /\//, "$dir_list[$i]";

and performs an operation on them, the results being assigned to a temp
array

: $dirnames[$i] = $tmp_fields[$#tmp_fields];

from which we build a third array consisting of the last element of the temp
array
: }
:
: Since I'm an extreme Perl newbie (started learning it this afternoon
::>), I'm just wondering is there a better, or more standard way of
: doing stuff like this?

The File::Basename module provides some functions for handling file paths,
but is also trivial to deal with in a regex. A single regex is not portable
(between win32, unix, mac etc) but for most small script purposes this is
not important. It should be borne in mind however.

Several ways to deal with this come to mind...

for (@dir_list){ # loop through array
if (m/.*\/(.*)/){ # capture part after last /
push @dirnames, $1: # push into array
}
}

This can be written as:

for (@dir_list){ # loop construct
push @dirnnames, $1 if m|.*/(.*)|; # test and assign
}

We test if the regex match succeeded before assigning the capture ($1)
because if not we might assign something we don't want.

The two regexes above, whilst the look different are actually the same. The
second one uses different delimiters for the match operator in order to
avoid backwacking the slash which can lead to 'leaning toothpick syndrome'
wherein it becomes hard to read what is part of the regex and what is an
escape. The regex works because it is greedy. The first .* grabs
everything, and then the regex backtracks until the / can match with the .*
following matching everything else. The parens capture everything after the
matched / into the first default variable $1.

Here is one using map:

@dirnames = map {m{.*/(.*)}} @dir_list;

Note the different delimiters for the match operator, this time m{} instead
of m|| or m//. The outer braces form the BLOCK for the map function. BTW,
using // is the only time you can drop the m// and write it like

/.*\/(.*)/;

instead of

m/.*\/(.*)/;

HTH
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top