【问题标题】:Ruby: nested regular expressions and string replaceRuby:嵌套正则表达式和字符串替换
【发布时间】:2010-10-25 02:38:30
【问题描述】:

我正在使用 CodeRay 进行语法高亮显示,但我遇到了这个正则表达式的问题。文本将如下所示:

<pre><code>:::ruby
def say_hello
  puts 'hello!'
end
</code></pre>

这部分::::ruby 将告诉 CodeRay 代码块应该被解释为哪种语言(但它必须是可选的)。所以这是我目前所拥有的:

def coderay(text)
  text.gsub(/\<pre\>\<code\>(.+?)\<\/code\>\<\/pre\>/m) do
    CodeRay.scan($2, $3).div()
  end
end

$2 包含我正在格式化的代码(包括说明将其格式化为哪种语言的行),但我需要提取第一行以便我可以将其作为第二个参数传递给 scan() 或如果找不到该语言行,则将其传递给默认参数。我该怎么做?

【问题讨论】:

  • 您使用的是 Ruby 1.8 还是 1.9?
  • 任一。有什么不同吗?
  • Ruby 1.9 中的 RE 支持命名组。此外,您只是希望 Ruby 成为默认语言,还是希望以更复杂的方式来确定将代码解释为哪种语言?

标签: ruby coderay


【解决方案1】:

在 Ruby 1.9 中,使用命名组:

default_lang=:ruby

def coderay(text)
  text.gsub(%r!<pre><code>(?::{3}(?<lang>\w+)\s+)?(?<code>.+?)</code></pre>!m) do
    if $~[:lang].nil?
      lang=default_lang
    else
      lang = $~[:lang].intern
    end
    CodeRay.scan($~[:code], lang).div()
  end
end

default_lang 也可以是类或对象变量而不是局部变量,具体取决于coderay 的上下文。

相同,但使用内联表达式来处理可选语言:

default_lang=:ruby

def coderay(text)
  text.gsub(%r!<pre><code>(?::{3}(?<lang>\w+)\s+)?(?<code>.+?)</code></pre>!m) do
    CodeRay.scan($~[:code], $~[:lang].nil? ? default_lang : $~[:lang].intern).div()
  end
end

第二个选项有点混乱,因此你might want to avoid it

事实证明,不匹配的可选组中的命名组仍然计入 Ruby,因此处理不匹配编号的组与不匹配的命名组没有任何不同,这与我最初的想法不同。因此,您可以将命名的组引用替换为上面的位置引用,它应该工作相同。

default_lang=:ruby

def coderay(text)
  text.gsub(%r!<pre><code>(?::{3}(?<lang>\w+)\s+)?(?<code>.+?)</code></pre>!m) do
    CodeRay.scan($2, $1.nil? ? default_lang : $1.intern).div()
  end
end

def coderay(text)
  text.gsub(%r!<pre><code>(?::{3}(?<lang>\w+)\s+)?(?<code>.+?)</code></pre>!m) do
    if $1.nil?
      lang=default_lang
    else
      lang = $1.intern
    end
    CodeRay.scan($2, lang).div()
  end
end

【讨论】:

  • 1.8 的语法是什么样的?
猜你喜欢
  • 1970-01-01
  • 2019-04-17
  • 2018-07-13
  • 2017-02-04
  • 1970-01-01
  • 1970-01-01
  • 2015-11-30
相关资源
最近更新 更多