2012-12-23 82 views
0

说我有这样的文字:红宝石GSUB '<' and '>'

foo 
{% highlight ruby %} 
bar < > 
{% endhighlight %} 

如何更换<>&lt;&gt;{% highlight ruby %}...{% endhighlight %}

str.gsub(/\{% highlight (\w*) %\}(.*)\{% endhighlight %\}/m, '<pre><code class="language-\1">\2</code></pre>') 
+0

你尝试'str.gsub (//m,'>')'? – orde

+0

呃,对不起。我忘了提及我只替换了{%highlight ruby​​%} ... {%endhighlight%}'内的'<' and '>'。 – dsdeiz

+0

你在说什么基本上是解析文档,这与正则表达式很难做到。不要使用自己的自制标记语言,而是使用HTML或Markdown。 –

回答

2

为什么另起炉灶?你不是第一个想要创建自己的标记语言的人,但有一些非常棒的。我个人喜欢Markdown,它在Github上有一个叫做RedCarpet的巨大ruby实现。你可以用这个宝石轻松解析文本。下面是一些示例代码:

require 'redcarpet' 

input = <<-EOF 
foo 

    bar < > 
EOF 

Redcarpet::Markdown.new(Redcarpet::Render::HTML).render(input) 
#=> <p>foo</p> 
#=> 
#=> <pre><code>bar &lt; &gt; 
#=> </code></pre> 

你可能已经注意到,该堆栈溢出采用降价的用户输入,所以我其实写我的答案在降价,现在;-)

+0

是的,我结束了使用Redcarpet。谢谢! – dsdeiz

1

使用GSUB和没有外部库,这将工作:

str.gsub(/</, "&lt;").gsub(/>/, "&gt;") 

或仅匹配您的{%...%}标记之外:

str.gsub(/(?<=%}|\A)(.+?)(?={%|\z)/) do |n| 
    n.gsub(/</, "&lt;").gsub(/>/, "&gt;") 
end 
我也要跟 <pre><code class="language-ruby">...</code></pre>使用这种替代 {% highlight ruby %}...{% endhighlight %}

上述较长的正则表达式仅将lookbehead和lookahead断言((?<=%}|\A)(?={%|\z))仅用于找到括号外的子字符串。

但是,最好的方法可能仍然是使用HTMLEntities宝石,因为它会一直更清晰你在做什么。

require 'htmlentities' 
HTMLEntities.new.encode(str) 

str.gsub(/(?<=%}|\A)(.+?)(?={%|\z)/) do |n| 
    HTMLEntities.new.encode(n) 
end 
+0

呃,对不起。我忘了提及我只替换了{%highlight ruby​​%} ... {%endhighlight%}'内的'<' and '>'。 – dsdeiz