Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a multi-line string and I'd like to only extract lines that match a certain pattern and discard the rest of the string.

Original string:

lorem ipsum dolor sit amet consectetur
nunc KEEP THIS LINE ut massa lorem
DO NOT KEEP THIS LINE aenean blandit
nunc KEEP THIS LINE et justo quis
praesent at velit felis vel

Desired final string:

KEEP THIS LINE ut massa lorem
KEEP THIS LINE et justo quis

The regex I have so far is:

(?ms).*?(?-s)^nunc (KEEP THIS LINE.*?$)

I can just replace the match with the backreference \1. However, this fails to replace from the end of the last matched pattern to the end of the string.

The regex:

(?ms).*?(?-s)(^nunc (KEEP THIS LINE.*?$)|(?s:).*?\Z)

successfully identifies the pattern between the last desired line and the end of the string, but I can't figure out how to remove it.

share|improve this question
You should always indicate which program you are using. There are almost always subtle differences between how two different programs implement regular expression, even if they're of the same "kind". – Dennis Feb 5 '13 at 20:47
up vote 0 down vote accepted

Replacing ^(?:nunc (KEEP THIS LINE.*)|.*\n)$ with \1 will achieve the desired output:

  • Due to the alternator (|), the expression ^(?:nunc (KEEP THIS LINE.*)?|.*\n)$ will forcefully match the entire line, without capturing it (?: designates a non-capturing group).

  • If the line begins with nunc KEEP THIS LINE, \1 will refer to the insides of the parentheses, i.e., the string beginning with KEEP THIS LINE and ending at the end of the line.

  • If the line does not begins with nunc KEEP THIS LINE, .*\n will match the entire line, including the terminating newline character.

The above regular expression works fine with Perl.

In Notepad++ with Windows line breaks, you can use this one instead:

^(?:nunc (KEEP THIS LINE.*)|.*(\r\n)?)

Note that this will only remove the last line, not remove it.

share|improve this answer
Thanks for the help. I was using notepad++, which the documentation says is essentially the same as Perl, however the above solution did not work. Everything mentioned above seems logical, I think it just fails for this specific implementation. The final regex that worked for me was the addition of the noncapturing symbol like you have: (?s).*?(?-s)(?:^nunc (KEEP THIS LINE.*?$)|(?s:).*\Z) – smaxey Feb 5 '13 at 22:54
There's a minor difference in how Perl and Notepad++ interpret the $ character here, but the major problem is the operating systems' line terminators. Linux uses \n after every line (including the last one), Windows uses \r\n (not necessarily after the last one). – Dennis Feb 6 '13 at 11:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .