Regex to replace substring occurrences *only* when they are enclosed between begin / end brackets

961 views Asked by At

regex problem in ruby, and for some reason, I need this in one line in gsub method of ruby

Suppose the input sample string variable is multi line string like below

begin1 item abc item abc item 
extra end1
begin2 item abc item abc extra end2
begin1 item abc item abc extra end1

The rule is to change all item which inside block begin1 and end1 into love, it may across multi lines

After replace, the output sample should be

begin1 love abc love abc love 
extra end1
begin2 item abc item abc extra end2
begin1 love abc love abc love end1  

The solution is something like this

puts sample.gsub!(/(begin1.*)item*(.*end1)/m,'\1love\2')
2

There are 2 answers

3
Alexis On BEST ANSWER

What about this one: sample.gsub!(/item(?=((?!begin1).)*end1)/m, 'love')?

And, to make the regex a little bit less magic:

/ 
  item              
  (?=               # look-ahead assertion
    (               
      (?!begin1)    # negative look-ahead assertion
      .             # any character that is not part of the 'begin1' sequence
    )*              # there's no 'begin1' after 'item' and before 'end1'
    end1            # there is 'end1' after 'item'
  )
/mx                 # /m - for multiline strings, x - for comments

(Note, that it will work correctly only if your 'markup' is 'correct' - e.g. there is no trailing ends or leading begins, no nesting blocks)

Also, I can't help to say that regexes is poor tool for such a task. Complex regular expressions are too incomprehensible and too unmaintainable, they are like black magic - you never know when they're gonna crash :)

1
Batkins On

I'm not entirely certain what you mean with the input part of your question, so I'm a bit confused but I think you're using the gsub method the wrong way. Try this:

> string = 'begin1 item abc item abc item'
=> "begin1 item abc item abc item"
> string.gsub(/item/, 'love')
=> "begin1 love abc love abc love"

It's a simple regular expression substitution method. Read the docs for more details on how to use it. I think you may be making it more complex than it needs to be.