Reputation: 309
I have a string say "a/b/c/d/e"
and I want to replace all except the last /
to . i.e my output should be a.b.c.d/e
.
How do I modify my substitute command s/\//./g
to do the same? Also note the hierarchy doesn't always have 4 "/
". It can be any number.
Upvotes: 3
Views: 1022
Reputation: 66873
Replace all /
for which there is a /
further down the string; thus that excludes the last /
perl -wE'$_ = q(a/b/c/d/e); s{/(?=.*?/)}{.}g; say'
This uses the positive lookahead, (?=...)
to assert the presence of /
further down (after .*?
), without consuming anything.
Another way is to capture with a negated character class pattern (and then put that back in the string) and use only the fixed string /
in the lookahead
s{/([^/]*)(?=/)}{.$1}g;
The first approach above with a /
match and a lookahead for the rest turns out to be faster. The likely reason is the capturing in the ([^/]*)
approach (and it has to copy that back in the string), whereby the first approach does a single character overwrite (the .*?
doesn't backtrack).
Benchmarked: 126% faster under v5.10.1 and v5.27.2 (desktop) and 110% with v5.16.1 (new server). Tested with 4-10 char long strings for four path components.
Thanks to ikegami for noting this and prompting for, and commenting on, the comparison.
Upvotes: 7