2010-10-25 63 views
0

我使用CodeRay進行語法高亮顯示,但是我遇到了這個正則表達式的問題。文本將是這樣的:Ruby:嵌套的正則表達式和字符串替換

<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()的第二個參數,或者如果未找到該語言行,則將其傳遞給默認參數。我怎樣才能做到這一點?

+0

您使用的是Ruby 1.8還是1.9? – outis 2010-10-25 03:01:08

+0

任一。這有什麼不同嗎? – Andrew 2010-10-25 03:25:44

+0

Ruby 1.9中的RE支持命名組。另外,你是否僅僅希望Ruby成爲默認的語言,或者你是否想要一種更復雜的方式來確定將代碼解釋爲什麼語言? – outis 2010-10-25 03:43:04

回答

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 
+0

1.8語法是什麼樣的? – Andrew 2010-10-25 04:01:28