简体   繁体   中英

Ruby gsub '<' and '>'

Say I have this text:

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

How do I replace < and > with &lt; and &gt; inside {% highlight ruby %}...{% endhighlight %} ? I'm also replacing {% highlight ruby %}...{% endhighlight %} with <pre><code class="language-ruby">...</code></pre> using this:

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

Why reinvent the wheel? You're not the first person wanting to create their own markup language, but there are some pretty awesome ones out there. I personally like Markdown which has a great ruby implementation called RedCarpet from the folks over at Github. You can easily parse text with this gem. Here's some example code:

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>

You may have noticed, that Stack Overflow uses Markdown for user input, so i am actually writing my answer in Markdown right now ;-)

Using gsub and no external libraries, this will work:

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

Or to only match outside of your {%...%} markup:

str.gsub(/(?<=%}|\A)(.+?)(?={%|\z)/) do |n|
  n.gsub(/</, "&lt;").gsub(/>/, "&gt;")
end

The longer regex above uses the lookbehind and lookahead assertions ( (?<=%}|\\A) and (?={%|\\z) ) to only find substrings that are outside of the brackets.

But, the best way would probably still be to use the HTMLEntities gem, since it will always be clearer what you are doing.

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

or

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM