我在Ruby中有一个正则表达式,它在多行模式下无法正常工作。
我正在尝试将Markdown文本转换为Redmine中使用的Textile-eque标记。问题出在我转换代码块的正则表达式中。它应该找到任何以4个空格或制表符引出的行,然后将它们包装在 pre 标记中。
markdownText = '# header
some text that precedes code
var foo = 9;
var fn = function() {}
fn();
some post text'
puts markdownText.gsub!(/(^(?:\s{4}|\t).*?$)+/m,"<pre>\n\\1\n</pre>")
预期结果:
# header
some text that precedes code
<pre>
var foo = 9;
var fn = function() {}
fn();
</pre>
some post text
问题是关闭 pre 标记打印在文档的末尾而不是“fn();”之后。我尝试了以下表达式的一些变体,但它不匹配:
gsub!(/(^(?:\s{4}|\t).*?$)+^(\S)/m, "<pre>\n\\1\n</pre>\\2")
如何使正则表达式仅与缩进的代码块匹配?您可以在Rubular here上测试此正则表达式。
答案 0 :(得分:12)
首先,请注意Ruby中的'm'
多行模式等同于其他语言的's'
单行模式。换一种说法; Ruby中的'm'
模式意味着:“dot match all”。
这个正则表达式可以很好地匹配类似markdown的代码部分:
re = / # Match a MARKDOWN CODE section.
(\r?\n) # $1: CODE must be preceded by blank line
( # $2: CODE contents
(?: # Group for multiple lines of code.
(?:\r?\n)+ # Each line preceded by a newline,
(?:[ ]{4}|\t).* # and begins with four spaces or tab.
)+ # One or more CODE lines
\r?\n # CODE folowed by blank line.
) # End $2: CODE contents
(?=\r?\n) # CODE folowed by blank line.
/x
result = subject.gsub(re, '\1<pre>\2</pre>')
这需要在代码部分之前和之后留空行,并允许代码部分内的空行。它允许\r\n
或\n
行终止。请注意,这不会删除每行前面的前4个空格(或制表符)。这样做需要更多的代码复杂性。 (我不是一个红宝石家伙,所以不能帮忙。)
我建议查看降价源本身,看看它是如何完成的。
答案 1 :(得分:0)
/ ^(\ S {4} | \吨)+ + \; \ N $ /米
效果更好,仍然会选择我们不想要的换行符。 here它是rubular。
答案 2 :(得分:0)
Here是另一个捕获单个块中所有缩进行的
((?:^(?: {4}|\t)[^\n]*$\n?)+)
答案 3 :(得分:0)
这对我的样本输入很有帮助。
markdownText.gsub(/\n?((\s{4}.+)+)/, "\n<pre>#{$1}\n</pre>")