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

Don*_*han 7 ruby regex multiline

我在Ruby中有一个正则表达式,在多行模式下无法正常工作.

我正在尝试将Markdown文本转换为Redmine中使用的Textile-eque标记.问题出在我转换代码块的正则表达式中.它应该找到任何带有4个空格或标签的行,然后将它们包装在标签中.

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>")
Run Code Online (Sandbox Code Playgroud)

预期结果:

# header

some text that precedes code

<pre>
    var foo = 9;
    var fn = function() {}

    fn();
</pre>

some post text
Run Code Online (Sandbox Code Playgroud)

问题是关闭标记打印在文档的末尾而不是"fn();"之后.我尝试了以下表达式的一些变体,但它不匹配:

gsub!(/(^(?:\s{4}|\t).*?$)+^(\S)/m, "<pre>\n\\1\n</pre>\\2")
Run Code Online (Sandbox Code Playgroud)

如何使正则表达式仅与缩进的代码块匹配?你可以在这里测试Rubular上的这个正则表达式.

rid*_*ner 12

首先,请注意'm'Ruby 中的多行模式等同于's'其他语言的单行模式.换一种说法; 'm'Ruby中的模式意味着:"点匹配所有".

这个正则表达式可以很好地匹配类似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>')
Run Code Online (Sandbox Code Playgroud)

这需要代码部分之前和之后的空白行,并允许代码部分本身内的空行.它允许任何一个\r\n\n行终止.请注意,这不会删除每行前面的前4个空格(或制表符).这样做需要更多的代码复杂性.(我不是一个红宝石家伙,所以无法帮助.)

我建议查看降价源本身,看看它是如何完成的.