سؤال

I'm parsing some text with a set of tags and replaces. For example, to make text **surrounded by double astersks** bold I use /\*\*([\s\S]+?)\*\*/gm for the pattern and "<b>$1</b>" for the replace. But what I want to also provide raw text like I did in this very question. So I need an expression which "matches any character including whitespaces and newlines surrounded by double asterisks but not surrounded by backticks with (optional) characters/whitespaces/newlines in between the backtick and double asterisks"

Example.

Input string: "Lorem ``ipsum **dolor** sit`` amet, **consectetur** adipisicing elit"

Result: "Lorem ipsum **dolor** sit amet, consectetur adipisicing elit"

I tried non-matching groups and lookaheads but for no avail. I know it can be done by for example replacing characters with html entities or just use some Markdown parser, but just for the sake of interest, how can this be done via pure Regex magic?

هل كانت مفيدة؟

المحلول

Life would be simpler with lookbehind assertions.

/((`)[\s\S]*?)?\*\*([\s\S]+?)\*\*([\s\S]*?\2)/gm

 

((`)[\s\S]*?)? #capture any characters (or none) preceded by a backtick (captured for a later use in the RE). Optionnal - non-greedy.
\*\*([\s\S]+?)\*\* #capture any characters surrounded by asterisks.
([\s\S]*?\2) #capture any characters (including empty string) followed by the capture #2 (empty or backtick).

If the first group is empty, the last one will match an empty string.

Then we filter our result.

var str = "Lorem `ipsum **dolor** sit` amet, **consectetur** adipisicing elit dolor `**sit amet**` adi";

str = str.replace(/((`)[\s\S]*?)?\*\*([\s\S]+?)\*\*([\s\S]*?\2)/gm, function(m, p1, p2, p3, p4){
    return p1 && p4 ? m : "<b>" + p3 + "</b>";
});

 

return p1 && p4 ? m : "<b>" + p3 + "</b>";

If p1 and p4 are not empty/undefined, that means our matched string starts and ends with backticks. We return it without changes.

This example outputs :

Lorem `ipsum **dolor** sit` amet, consectetur adipisicing elit dolor `**sit amet**` adi

It's a bit tricky, imo. But as you point out, it's just for the sake of interest. ;)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top