Home > OS >  Regex that matches strings only within a larger match
Regex that matches strings only within a larger match

Time:10-10

I'm looking to create a single regex (for use in an Obsidian plugin) that will match certain lines under a specific Markdown header. Here's the source text:

# Inbox
​
- [ ] task 1
​
​
# Now
​
- [ ] task 2
- [ ] task 3
    - test bullet note
    - another bullet note
- [ ] task 4
​
# Next Actions
​
- [ ] task 5

I'd like the regex to capture all "tasks" under the header "# Now". Here, that would be task 2, task 3 (and its notes), and task 4.

I have the following regex which successfully captures tasks, but I don't know how to specify only tasks under that header.

^[ \t]*(-|\*|\d*\.) \[[xX ]\].*$

CodePudding user response:

For the example data, you might use a lookbehind assertion for the # Now part, and then match the - [ ] part followed by all lines that do not start with that pattern.

(?<=^# Now\n(?:(?!\n# \w)[^])*)-[ \t]*\[[^][]*].*(?:\n[ \t] -.*)*

The pattern matches;

  • (?<= Positive lookbehind
    • ^# Now\n Match literally at the start of the line
    • (?:(?!\n# \w)[^])* Match any char asserting not the # \w pattern directly to the right
  • ) Close the lookbehind
  • -[ \t]*\[[^][]*] Match - and optional spaces and then [...]
  • .* Match the rest of the line
  • (?:\n[ \t] -.*)* Optionally repeat all lines that do not start with the -[...] pattern

Regex demo

  • Related