I can't find a word in line with the line started special word. For example;
Mike likes banana, kiwi and grapes.
Mary likes banana, apple and watermelon.
I made a mistake in Mary's favorite fruit. I want to change banana
to orange
. But how can find banana
only starting with Mary line. I need ruby regex because of I am using it in chef cookbook.
Before;
Mike likes banana, kiwi and grapes.
Mary likes banana, apple and watermelon.
After;
Mike likes banana, kiwi and grapes.
Mary likes orange, apple and watermelon.
Best Regards
Hasan
We may construct the method
def sub_word(str, person, word, replacement)
str.sub(/^(?=.*\b#{person}\b).*\K\b#{word}\b/, replacement)
end
I will display several examples for which the first line of the string (str
) and last three arguments are fixed, namely
f = "Mike likes banana, kiwi and grapes.\n"
person = "Mary"
word = "banana"
replacement = "orange"
It is convenient to write
args = ["Mary", "banana", "orange"]
The only thing that changes in the examples is the second line of the string, (containing "Mary"
).
The examples considered are as follows.
sub_word(f + "Mary likes banana, apple and melon.", *args)
#=> "Mike likes banana, kiwi and grapes.\nMary likes orange, apple and melon."
sub_word(f + "Mary likes apple, banana and melon.", *args)
#=> "Mike likes banana, kiwi and grapes.\nMary likes apple, orange and melon."
sub_word(f + "Yes, Mary is fond of apple, banana and melon.", *args)
#=> "Mike likes banana, kiwi and grapes.\nYes, Mary is fond of apple, orange and melon."
sub_word(f + "Apple, banana and melon are liked by Mary.", *args)
#=> "Mike likes banana, kiwi and grapes.\nApple, orange and melon are liked by Mary."
sub_word(f + "Mary likes pear, apple and melon.", *args)
#=> "Mike likes banana, kiwi and grapes.\nMary likes pear, apple and melon."
sub_word(f + "Maryann likes banana, apple and melon.", *args)
#=> "Mike likes banana, kiwi and grapes.\nMaryann likes banana, apple and melon."
sub_word(f + "Mary likes bananas, apple and melon.", *args)
#=> "Mike likes banana, kiwi and grapes.\nMary likes bananas, apple and melon."
In all examples the regular expression used by String#sub evaluates to the following.
/^(?=.*\b#{person}\b).*\K\b#{word}\b/
#=> /^(?=.*\bMary\b).*\K\bbanana\b/
The elements of the expression are as follows.
^ match the beginning of a line
(?= begin a positive lookahead
.* match zero or more characters other than line terminators,
as many as possible
\bMary\b match 'Mary' with word boundaries before and after
) end positive lookahead
.* match zero or more characters other than line terminators,
as many as possible
\K reset the starting point of the reported match and exclude
any previously consumed characters in the final match
\bbanana\b match 'banana' with word boundaries before and after
Note that the positive lookahead asserts that the string "Mary"
is somewhere in the line.