senorsmile
senorsmile

Reputation: 760

s|\b-d\b|| regex not working as expected

The following one liner is not working as I'd expect:

echo "--tags hi -d -e foo=bar" | perl -ne '$_ =~ s|\b-d\b||; print $_'

The "-d" remains. After looking at it for 15 minutes, I decided I should get help.

This does work ok:

echo "--tags hi -d -e foo=bar" | perl -ne '$_ =~ s|-d||; print $_'

but of course may not always work... i.e. I need word boundary markers in the search.

Upvotes: 0

Views: 194

Answers (2)

ysth
ysth

Reputation: 98398

\b does not mean is preceded or followed by whitespace, it means a word boundary (a transition into or out of a sequence of word characters); since - is not a word character, \b- means - has to have a word character before it.

I'm guessing maybe you mean s|(?<!\S)-d(?!\S)|| (-d neither preceded nor followed by a non-whitespace character.

See the code in use here

Upvotes: 6

ikegami
ikegami

Reputation: 386396

Unlike d, - isn't a word char, so use (?<!\w) instead of \b.


\b

means

# At a word char that's not preceded by a word char, or
# after a word char that's not followed by a word char.
(?<!\w)(?=\w) | (?<=\w)(?!\w)

so

\b -d \b

means

(?: (?<!\w)(?=\w)|(?<=\w)(?!\w) ) -d (?: (?<!\w)(?=\w)|(?<=\w)(?!\w) )

Since - isn't a word char, and since d is a word char, the above simplifies to the following:

(?<=\w) -d (?!\w)

If - was a word char, the above would simplify to the following instead:

(?<!\w) -d (?!\w)

That is what you want, or just

(?<!\w) -d \b

(Spaces added for readability. Either remove the spaces or use /x.)

Upvotes: 2

Related Questions