Jon Scobie
Jon Scobie

Reputation: 580

Regular expression and how to include a matching string but exclude matching string ending with an underscore?

I have tried so many ways to solve this in perl/sed and read up quite a bit about negative lookaheads etc but still the match doesn't work.
I have lines such as :-

for (vector<some__header>::const_iterator header = some__header_->begin(); header != some__header_->end(); ++header)  

and

for (vector<some__trailer>::const_iterator header = some__trailer_->begin(); header != some__trailer_->end(); ++header)  

I want to replace text matching some__value with other__value but not any text which matches some__value_

So, if I was to replace some with other for the first line, I'd get :-

for (vector<other__header>::const_iterator header = some__header_->begin(); header != some__header_->end(); ++header)  

Obviously, something like (in perl) :-

(some)__([a-zA-Z]*)(?!_)

is not working as it will match some__heade as well.
What's the magic regex part I'm missing?

Upvotes: 2

Views: 72

Answers (3)

Bohemian
Bohemian

Reputation: 425033

Just capture the trailing non-underscore too:

sed 's/some\(__[a-zA-Z]*[^a-zA-Z_]\)/other\2/g'

The key is the negated character class can't just be [^_] because that allows the last letter of the name to be the non-underscore.

Also note the slight rearrangement to simplify things

Upvotes: 1

Birei
Birei

Reputation: 36262

Using and a possesive quantifier for alphas:

perl -pe 's/some(__(?>[[:alpha:]]*))(?!_)/other$1/g' infile

With an example line of:

for (vector<some__header>::const_iterator header = some__header_->begin(); header != some__header->end(); ++header)  some__header_

It yields:

for (vector<other__header>::const_iterator header = some__header_->begin(); header != other__header->end(); ++header)  some__header_

Upvotes: 0

devnull
devnull

Reputation: 123508

You could say:

sed 's/some__header[^_]/other__value/g' filename

Also,

sed 's/some__[^_]*[^_]/other__value/g' filename

If only some is to be replaced with other, say:

sed 's/some__\([^_]*\)[^_]/other__\1/g' filename

Upvotes: 1

Related Questions