如何在Ruby中修复此多行正则表达式?

时间:2011-04-19 16:08:12

标签: ruby regex multiline

我在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上测试此正则表达式。

4 个答案:

答案 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>")