Markdown paragraph tag regex

Viewed 522

I'm after a regex which can support the following test case:

This should
all be
one match

#this should not match
1. nor this
> nor this
this should be a second match

So I can then wrap these two matches in <p> tags. However, I'm getting stuck on the newlines: two should break the match, but one newline cannot. Here's the closest I've come:

(^[A-z].+)

This correctly grabs all the desired text, but forms four matches instead of the desired two.

On Regexr

Thank you for your time.

3 Answers

You can use

/^[A-Za-z].*(?:\n[A-Za-z].*)*/gm

See the regex demo.

Details

  • ^ - start of a line (due to m modifier)
  • [A-Za-z] - an ASCII letter
  • .* - the rest of the line
  • (?:\n[A-Za-z].*)* - zero or more lines starting with an ASCII letter.

This is not something you can likely do with a single regular expression. While it is true that some Markdown implementations use regex as their primary tool for parsing Markdown, they use a series of expressions to do so (see the original implementation, markdown.pl, for example).

For example, you might have an expression which matches headers, an expression which matches list items, an expression which matches blockquotes and an expression which matches any block of text. Each of those expressions would be run against the input in turn. However, by the time that the last expression is run, the previous expressions in the series have already consumed the various other elements. Therefore, the final expression for matching paragraphs does not need to account for matches of headers, lists or blockquotes.

In fact, if you were to remove the header expression from markdown.pl, then all headers would simply be wrapped in <p> tags with the hashes (#) still included in the text.

My point is you would need to implement a full Markdown parser. However, there are many implementations that already exist. You would likely be better off using one which already exists. In fact, most modern implementations generate an abstract syntax tree (AST) rather than doing regex substitutions (as pointed out in another answer).

Related