A zero-width positive lookbehind assertion

G

George

Hi
I am trying to get directory name from say a path
c:/app/organizer
what I want to get is organizer , so basically if I search from end
of string and then lookbehind
($name)=($path=~(/(?<=\/)(.*?)(.*?)\z/));

but it does not result in getting to oraginzer , it fetches app/
organizer , kind of greedy

I know I can do it using FILE::BASENAME , but want to understand how
to do it using regexp and look back
thaks
/g
 
X

Xho Jingleheimerschmidt

George said:
Hi
I am trying to get directory name from say a path
c:/app/organizer
what I want to get is organizer , so basically if I search from end
of string and then lookbehind
($name)=($path=~(/(?<=\/)(.*?)(.*?)\z/));

How would the zero-width look behind change anything? If the slash
itself isn't captured in $1 or $2, who cares if it is in $& ?
but it does not result in getting to oraginzer , it fetches app/
organizer , kind of greedy

In my hands, $name ends up as the empty string. What you indicate ends
up in $2, not in $1 or $name.
I know I can do it using FILE::BASENAME , but want to understand how
to do it using regexp and look back
thaks
/g

/([^\/]*)\z/

No look behind needed.

Xho
 
C

C.DeRykus

Hi
I am trying to get directory name from say a path
c:/app/organizer
what I want to get is organizer , so basically  if I search from end
of string and then lookbehind
($name)=($path=~(/(?<=\/)(.*?)(.*?)\z/));

but it does not result in getting to oraginzer , it fetches app/
organizer , kind of greedy

I know I can do it using FILE::BASENAME , but want to understand how
to do it using regexp and look back

Here's a possible lookbehind solution:

( $name ) = $path =~ m{ (?<=/) ([^/]*) \z }x;


or, with 5.10 you could use \K (perldoc perlre):

( $name ) = $path =~ m{ / \K ([^/]*) \z }x;



But, the above are somewhat obfuscated because there's a
straightforward, simpler alternative:

( $name ) = $path =~ m{ / ([^/]*) \z }x


The only difference is that $& now includes '/'; whereas,
the latter doesn't.
 
D

Dr.Ruud

C.DeRykus said:
( $name ) = $path =~ m{ / ([^/]*) \z }x

That $name will end up false if there is no slash in $path.

perl -Mstrict -le '
for my $path (undef, "", "test", "test/123") {
my ($name) = $path =~ m~([^/]+)\z~;
print defined($name) ? "<$name>" : "undef";
}
'
undef
undef
<test>
<123>

But you should just use File::Basename for this.
(beware, the module name was grossly misspelled by OP)
 
C

C.DeRykus

C.DeRykus said:
( $name ) = $path =~ m{  / ([^/]*) \z }x

That $name will end up false if there is no slash in $path.

perl -Mstrict -le '
   for my $path (undef, "", "test", "test/123") {
     my ($name) = $path =~ m~([^/]+)\z~;
     print defined($name) ? "<$name>" : "undef";
   }
'
undef
undef
<test>
<123>

But you should just use File::Basename for this.
(beware, the module name was grossly misspelled by OP)

I could be wrong but the OP sounded more interested in
how regex lookbehind could be used in a specific case
than generating a drop-in replacement for File::Basename.
But, I agree it's worth noting the limitations and correct
spelling.
 

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,995
Messages
2,570,236
Members
46,825
Latest member
VernonQuy6

Latest Threads

Top