2012-10-11 19 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 + +)和空白字符在开始/结束,除此之外,这是伎俩,我认为