tags:

views:

233

answers:

2

hi

There is an array of strings

    paths = ['foo/bar_baz/_sunny', bar/foo_baz/_warm', 'foo/baz/_cold', etc etc]

I need to remove underscore in each last part of path (_sunny => sunny, _warm => warm, _cold => cold)

    paths.each do |path|
        path_parts = path.split('/')
        path_parts.last.sub!(/^_/, '')
        puts path_parts.join('/')
    end

However that solution is a bit dirty. I feel it can be done without using path.split and path.join. Do you have any ideas?

Thanks in advance

+2  A: 

I don't know Ruby, but the pattern

/('[a-zA-Z0-9_\/]*\/)_([a-zA-Z0-9_]*')/g

could be replaced with

'$1$2'

if $x is used in Ruby to reference matching groups, and g is valid flag. It would need to be applied once to the string, with no splits or joins.

Daniel
thanks! that solves the problem
mlomnicki
so accept Daniel's answer
mikej
+2  A: 

Or, more compactly:

paths.map {|p| p.sub(/_(?=[^\/]*$)/,"")}

That is, strip out any underscore that is followed by any number of non-slashes and then the end of the string...

glenn mcdonald
very nice! but what does '?=' mean in regexp?
mlomnicki
"`?=`" is a non-matching look-ahead. In that example, it will match "_" only if the next characters are such as indicated, but those next characters won't be part of the match. That way, where "_" gets replaced, you don't need to repeat the characters appearing after it. My own solution could use `?<` and `?=` to avoid having to use groups. It can lead to significant performance gains.
Daniel
Thank you very much for explanation, Daniel!
mlomnicki