RegEx to start with the last occurance of the string

Viewed 45

I have a text file with a data set I want to remove some records from. It looks like this:

  1. =separator=
  2. data
  3. unwantedKeyword
  4. data
  5. =separator=
  6. data
  7. wantedKeyword
  8. data
  9. =separator=
  10. data
  11. unwantedKeyword
  12. data
  13. =separator=
  14. data
  15. wantedKeyword
  16. data
  17. =separator=

I can use a certain keyword to identify records I don't want (or want). I wanted to use RegEx utilizing this keyword and a separator string to remove all those expressions. Removing the "bottom" part of the record works fine, but when I try to remove the "top" bit using this:

=separator=.*?unwantedKeyword

the start of the match is on the 1st available =separator= (line 5.) rather than the last one (line 9.) before the end keyword (line 11.) resulting in wanted records being removed.

Is it possible to match only the last instance of that string (=separator= in the mock data) so only lines 1. to 3. and 9. to 10. rather than 1. to 3. and 5. to 11. would be replaced?

EDIT:

Or I guess just make it read the file in backward direction? Notepad++ disables that option for RegEx tho, so not sure if that's possible either.

2 Answers

If you want to remove line 1 to 3 and line 9 to 11, you can use a lookahead to prevent matching all the lines that either start with =separator= or contain unwantedKeyword.

^=separator=.*(?:\R(?!(?:=separator=|.*?\bunwantedKeyword\b)).*)*\R.*?\bunwantedKeyword\b.*\R*

Regex demo

enter image description here

I'd use

(?s)=separator=(?:(?!=separator=).)*?unwantedKeyword

See proof.

Explanation

--------------------------------------------------------------------------------
  (?s)                     set flags for this block (with . matching \n) 
--------------------------------------------------------------------------------
  =separator=              '=separator='
--------------------------------------------------------------------------------
  (?:                      group, but do not capture (0 or more times
                           (matching the least amount possible)):
--------------------------------------------------------------------------------
    (?!                      look ahead to see if there is not:
--------------------------------------------------------------------------------
      =separator=              '=separator='
--------------------------------------------------------------------------------
    )                        end of look-ahead
--------------------------------------------------------------------------------
    .                        any character
--------------------------------------------------------------------------------
  )*?                      end of grouping
--------------------------------------------------------------------------------
  unwantedKeyword          'unwantedKeyword'
Related