sunknudsen
sunknudsen

Reputation: 7260

How to capture content of following markdown comments using regular expression?

I currently use /^<!--\n((.|\n)*)\n-->/ but all lines between first <!-- and last --> are captured.

<!--
Title: Foo
-->

# This is a test

<!--
Title: Bar
-->

Upvotes: 0

Views: 369

Answers (2)

Casimir et Hippolyte
Casimir et Hippolyte

Reputation: 89557

You use a greedy quantifier (quantifiers are by default greedy) instead of a lazy/non-greedy/reluctant quantifier. Many posts are related to this problem but this isn't the only problem of your pattern.

You use (.|\n)* to spread over multiple lines: that is correct but not efficient for backtracking regex engines (you can use that with grep or sed but this is better to avoid it with Javascript/PHP/Python/Ruby...). A way consists of using [\s\S]*, but in your particular case you can also use a more descriptive subpattern, since the starting tag is followed by a newline and the closing tag is preceded with a newline.

To reduce the number of tests needed by something like \n[\s\s]*?\n--> (that tests for each character taken by [\s\S]*? if \n--> follows), you can replace [\s\S]*? with .*(?:\n.*)*?. This time, \n--> is only tested once per line instead of once per character.

The pattern becomes /^<!--\n(.*(?:\n.*)*?)\n-->/gm.

But there's always a problem: What about empty comments since there's 2 mandatory newlines in this pattern? (an empty comment has only one newline.)

You can use: ^<!--\n(.*(?:\n.*)*?)\n?^-->/gm demo

This pattern makes the last \n optional to allow to capture the empty string with a simple alternation. On the other hand, to ensure that this one is present when the comment isn't empty, I added the anchor ^.

Upvotes: 0

GirkovArpa
GirkovArpa

Reputation: 4912

You're missing the lazy ? quantifier, as the comments pointed out. That's all.

const regex = /^<!--\n((.|\n)*?)\n-->/gm;
const string = `<!--
Title: Foo
-->

# This is a test

<!--
Title: Bar
-->`;
const matches = string.match(regex);
console.log(matches);

Upvotes: 4

Related Questions