Reputation: 580
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
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
Reputation: 36262
Using perl 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
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