Regexp获取两个Markdown标题/节之间的内容

时间:2018-06-19 00:46:01

标签: ruby-on-rails ruby regex

我正在尝试获取两个markdown标头之间的内容,第二个分隔标头是可选的。我希望regexp能够支持所有类型的标题,例如

### Thing

# Thing #

Thing
=====

基于this answer这是我到目前为止(假设我想获得标题为'Stuff'的标题的所有内容):

^\s*#*\s*Stuff.*\n([\W\w]*?)(?:^\s*#*\s*\w+.*\n(?:\s*[-=]*\s*\n)?|\z)

但是捕获组返回一个空字符串(link)。对于以下情况,解决方案应该能够返回“我的内容”:

## Stuff
my content

2

# Stuff #
my content

3

# Thing
texty text

#Stuff
my content

# Other thing

4

Stuff
====
my content

如果结果中有额外的新行或空格,那就没问题。这假设我想要的内容中没有子标题。

1 个答案:

答案 0 :(得分:1)

你的正则表达式中的第一个问题是“下一个标题检测器”((?:^\s*#*\s*\w+.*\n(?:\s*[-=]*\s*\n)?|\z))将匹配``!所以它匹配你标题后面的第一个空字符串(因为组捕获是非贪婪的)并且将捕获留空。第二个问题是你只匹配以表格“Stuff”开头的标题 # Stuff,而不是模式

Stuff
=====

最后,由于您捕获了下一个标题,因此无法正确地连续输入“Stuff”标题。

这是修复你的正则表达式的提议:
^(?<header>\s*#+\s*Stuff.*|\s*Stuff.*\n\s*(?:-{2,}|={2,}))\n(?<content>[\W\w]*?)(?=^(?:\s*#+|.*\n\s*(?:-{2,}|={2,}\s*\n))|\z)
要小心Ruby并不完全是PCRE,因此使tests on Rubular更准确,尽管它比tests on Regex101

更不方便用户使用