2

I'm trying to grab todo items from the following example text.

|| This is title ||

- item1
- item2
- item3

|| This is another title ||

I've tried with /|| This is title ||\n\n(.*)+/ but it only grabs item1 and I honestly have no idea how to write regex for the `|| This is another title ||

I would like to grab item1~3

왕뚜껑
  • 73
  • 5

2 Answers2

2

To get the title and the items separated in two groups, you could use a tempered greedy token (originally from here) as in

^\|\|\s+([^\n|]+)\s+\|\|((?:(?!^\|\|).)+)

This captures the title in the first group and all of the items in the second. See a demo on regex101.com (and mind the singleline mode!).


Broken down, this reads:

^\|\|\s+            # start of the line, "||" and whitespace
([^\n|]+)           # anything not "|" nor a newline - the title
\s+\|\|             # whitespace, "||"
(
    (?:(?!^\|\|).)+ # a neg. lookahead (?!...) that makes sure that no
)                   # line is captured that starts with "||"

Afterwards, you could simply get all your items with ^-(.+) from within the second group.

Jan
  • 42,290
  • 8
  • 54
  • 79
2

Another option could be repeatedly matching all lines that start with - in a group.

Then you might trim the result, and split on a newline.

^\|\|\s.*\s\|\|\n((?:\n- .*)+)
  • ^ Start of string
  • \|\|\s.*\s\|\|\n Match || till || at the end followed by the first newline
  • ( Capture group 1
    • (?:\n- .*)+ Match a newline, - and the rest of the line
  • ) Close group

Regex demo

const regex = /^\|\|\s.*\s\|\|\n((?:\n- .*)+)/gm;
const str = `|| This is title ||

- item1
- item2
- item3

|| This is another title ||`;

Array.from(
  str.matchAll(regex), m => console.log(m[1].trim().split("\n"))
);
The fourth bird
  • 154,723
  • 16
  • 55
  • 70