1

我正在编写一个脚本来迁移一些博客文章。

每篇博文都可能包含降价缩进的代码示例。其中一些有第一行,以三个冒号和一个语言标识符开头。

    ::: 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 代码不会有问题。

谢谢。

4

3 回答 3

0

您使用该m选项很好,但使用该选项没有意义,i因为您的正则表达式中没有字母。您可能希望在匹配后将语言名称小写或大写等。请注意,\s包括换行符。

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

或者,如果您可能使用的是非 linux,那么

/^ {4}:::[ \t]*(\w+)[ \t]*#{$/}((?: {4}[^#{$/}]*#{$/})*)/m
于 2012-10-11T10:14:21.700 回答
0

更新:

好的,原来换行问题来自我的 Opera 浏览器。

当我在 chrome 中检查您的原始链接时,它似乎有点工作,但匹配太多。

所以你唯一的问题是让你的正则表达式不贪婪

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

在 Rubular 上看到它

原答案:

如果我将您的正则表达式更改为

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

它会起作用,在rubular上看到它

您的正则表达式中似乎有(至少在 Rubular 上)三个问题:

  1. 有一个换行符\r\n,所以你\n一个人不匹配。

  2. $并不真正匹配换行符,它在 a 之前匹配\n,所以如果你的换行符是,这会咬你\r\n

  3. {0} 没用,事实上,如果我把它放在某个地方,rubular 就会停止匹配任何东西。

我将其更改.*为不贪婪的版本.*?,否则它会匹配太多。

于 2012-10-11T10:09:48.317 回答
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++)和开头/结尾的空白字符,除此之外,我认为这可以解决问题

于 2012-10-11T10:48:59.973 回答