2012-10-11 23 views
1

我正在寫一個腳本來遷移一些博客文章。正則表達式來替換coderay代碼示例與紅寶石

每篇博文都可能包含縮減縮進的代碼示例。其中一些有第一行,以三個冒號和一個語言標識符開頭。

::: ruby 
    def test 
     puts "meh" 
    end 

這些是更大的文字的一部分。

現在,對於任何給定的文本,我想找到這些代碼塊,並用此代替他們:

{% codeblock lang:ruby %} 
def test 
    puts "meh" 
end 
{% endcodeblock %} 

如果沒有三個冒號或語言標識,我想省略lang:<lang>位。

我目前在如何寫一個正則表達式來找到這些難住。我只能想出這是惡法,而不是工作獸:

/^\s{4}(:::(\w+))+\n(\s{4}.*)\n^\s{0}$/mi 

詳見http://www.rubular.com/r/kycM8SDQLb

什麼是更新每篇文章的正確方法?我只是在處理正則表達式,Ruby代碼不會成爲問題。

謝謝。

回答

0

更新:

OK,原來是換行問題從我的Opera瀏覽器來了。

當我檢查你的原始鏈接在鉻,似乎它是一種工作,但是匹配太多。

所以你唯一的問題是讓你的正則表達式ungreedy

^\s{4}(:::(\w+))+\n(\s{4}.*?)\n^$ 

看到它here on Rubular

原來的答案:

如果我改變你的正則表達式來

^\s{4}:::(\w+)\r\n({4}.*?)^\r$ 

它會工作,see it on rubular

你似乎有(至少在Rubular)三個問題在你的正則表達式:

  1. 斷行有\r\n,所以只有你\n不匹配。

  2. $並沒有真正匹配一個換行符,它\n之前相匹配,所以這會咬你,如果你的斷行是\r\n

  3. {0}是沒用的,其實rubular如果我把它停止匹配什麼在某處。

我改變了.*到ungreedy版本.*?否則它會匹配過多。

+0

看起來你的鏈接不起作用... – halfelf

+0

@halfelf,嘗試[這個鏈接](http://www.rubular.com/r/2iUUWxlgIP),似乎是換行符問題不是特定的ruby,它依賴於瀏覽器。我原來的鏈接在Opera中工作。 – stema

+0

這一個工程:)我在OSX 10.8上使用safari 6。 – halfelf

0

這很好,您使用的是m選項,但使用i選項沒有意義,因爲在正則表達式中沒有字母表。比賽結束後,您可能想要降低或提高語言名稱等。請注意,\s包含換行符。

/^ {4}:::[ \t]*(\w+)[ \t]*\n((?: {4}[^\n]*\n)*)/m 

或者,如果你可以是使用非Linux,然後

/^ {4}:::[ \t]*(\w+)[ \t]*#{$/}((?: {4}[^#{$/}]*#{$/})*)/m 
0

假設你解析代碼轉換成文本,試試這個:

str = %Q{:::ruby 
def test 
    puts "meh" 
end} 

str2 = %Q{def test 
    puts "meh" 
end} 

str.gsub(/^\s*(:::\s(\w+))?((.|\s)+)/) do 
    "{% codeblock#{" lang:#{$1}" if $1} %}#{$3}{% endcodeblock %}" 
end 
str2.gsub(/^\s*(:::\s(\w+))?((.|\s)+)/) do 
    "{% codeblock#{" lang:#{$1}" if $1} %}#{$3}{% endcodeblock %}" 
end 

什麼可適應的正則表達式的語言名稱(也許它不會捕捉c + +)和空白字符在開始/結束,除此之外,這是伎倆,我認爲