Atom regexp: discarding multiline text around blocks

Viewed 48

Assume I have this text:

blah blah Bob Loblaw Law blah
keep1 { i want this } blop
blah blob keep2 { and
this too } blaw blat
etc...

And I want to end up with

keep1 { i want this }
keep2 { and
this too }

or perhaps:

keep1 { i want this }
keep2 { and this too }

I haven't figured out how to get Atom's regexp find/replace mechanism to discard everything across multiple lines outside of a specific matching string. Hints?

update:

Of the many things I've tried, this gets me closest:

[\S\s]+?(keep\d\s+\{[\S\s]+?\})

which results in:

keep1 { i want this }
keep2 { and
this too }
 blaw blat
etc...

This is probably good enough -- I can edit the trailing shards -- but it would be useful to know how to trim those as well.

2 Answers

You may use this simple regex replace in Atom for this task:

\b(keep\d+\s*{[^}]*})|.+?

Replace it with: $1

RegEx Demo

RegEx Details:

  • \b: Word boundary
  • (keep\d+\s*{[^}]*}): In capture group #1 match a string that starts with keep followed by 1+ digits followed by 0+ whitespaces followed by any text that is inside {...} spanning across the lines as well. This assumes { and } are balanced and there is no escaping of { and }.
  • |: OR
  • .+?: Lazily match 1+ of anything

PS: If you want to remove leading line break then use:

\n?\b(keep\d+\s*{[^}]*})|.+?

Atom Editor Demo

Before replacement:

enter image description here

After replacement:

enter image description here

Use

[\s\S]*?(keep\d\s+\{[^{}]*\})|(?:(?!keep\d\s+\{[^{}]*\})[\s\S])+$

See proof.

EXPLANATION

--------------------------------------------------------------------------------
  [\s\S]*?                 any character of: whitespace (\n, \r, \t,
                           \f, and " "), non-whitespace (all but \n,
                           \r, \t, \f, and " ") (0 or more times
                           (matching the least amount possible))
--------------------------------------------------------------------------------
  (                        group and capture to \1:
--------------------------------------------------------------------------------
    keep                     'keep'
--------------------------------------------------------------------------------
    \d                       digits (0-9)
--------------------------------------------------------------------------------
    \s+                      whitespace (\n, \r, \t, \f, and " ") (1
                             or more times (matching the most amount
                             possible))
--------------------------------------------------------------------------------
    \{                       '{'
--------------------------------------------------------------------------------
    [^{}]*                   any character except: '{', '}' (0 or
                             more times (matching the most amount
                             possible))
--------------------------------------------------------------------------------
    \}                       '}'
--------------------------------------------------------------------------------
  )                        end of \1
--------------------------------------------------------------------------------
 |                        OR
--------------------------------------------------------------------------------
  (?:                      group, but do not capture (1 or more times
                           (matching the most amount possible)):
--------------------------------------------------------------------------------
    (?!                      look ahead to see if there is not:
--------------------------------------------------------------------------------
      keep                     'keep'
--------------------------------------------------------------------------------
      \d                       digits (0-9)
--------------------------------------------------------------------------------
      \s+                      whitespace (\n, \r, \t, \f, and " ")
                               (1 or more times (matching the most
                               amount possible))
--------------------------------------------------------------------------------
      \{                       '{'
--------------------------------------------------------------------------------
      [^{}]*                   any character except: '{', '}' (0 or
                               more times (matching the most amount
                               possible))
--------------------------------------------------------------------------------
      \}                       '}'
--------------------------------------------------------------------------------
    )                        end of look-ahead
--------------------------------------------------------------------------------
    [\s\S]                   any character of: whitespace (\n, \r,
                             \t, \f, and " "), non-whitespace (all
                             but \n, \r, \t, \f, and " ")
--------------------------------------------------------------------------------
  )+                       end of grouping
--------------------------------------------------------------------------------
  $                        before an optional \n, and the end of the
                           string
Related