Efficient way to remove text after a regular expression match

Viewed 309

Let's say I'd like to remove a space after every word. In reality, the regular expression before the space is more complex.

$text =~ s/(\w+) /$1/g;

works as expected, but I don't like the need for the $1, because it doesn't seem to be very efficient to match something, remove it and insert it again. I tried a positive lookahead, but this doesn't work:

$text =~ s/(?=\w+) //g;

I understand that it doesn't work because the "position" does not change with this lookahead. Is there another way to get rid of the $1?

1 Answers

s/// doesn't modify the original string, but builds up an a new one, so it's gonna copy the prefix anyway.[1] The capture itself can slow things down, but I think that's been improved. That said, \K does exactly what you want.

$text =~ s/\w\K //g;

  1. You can see the original scalar doesn't change until every substitution is complete:

    $ perl -e'$_ = "a-b-c-d"; s{-}{ CORE::say; "+" }eg; CORE::say;'
    a-b-c-d
    a-b-c-d
    a-b-c-d
    a+b+c+d
    
Related