问题
I'm trying to sanitize some HTML and just remove a single tag (and I'd really like to avoid using nokogiri, etc). So I've got the following string appearing I want to get rid of:
<div class="the_class>Some junk here that's different every time</div>
This appears exactly once in my string, and I'd like to find a way to remove it. I've tried coming up with a regex to capture it all but I can't find one that works.
I've tried /<div class="the_class">(.*)<\/div>/m
and that works, but it'll also match up to and including any further </div>
tags in the document, which I don't want.
Any ideas on how to approach this?
回答1:
I believe you're looking for an non-greedy regex, like this:
/<div class="the_class">(.*?)<\/div>/m
Note the added ?
. Now, the capturing group will capture as little as possible (non-greedy), instead of as most as possible (greedy).
回答2:
Because it adds another dependency and slows my work down. Makes things more complicated. Plus, this solution is applicable to more than just HTML tags. My start and end strings can be anything.
I used to think the same way until I got a job writing spiders and web-site analytics, then writing a big RSS-aggregation system -- A parser was the only way out of that madness. Without it the work would never have been finished.
Yes, regex are good and useful, but there are dragons waiting for you. For instance, this common string will cause problems:
'<div class="the_class"><div class="inner_div">foo</div></div>'
The regex /<div class="the_class">(.*?)<\/div>/m
will return:
"<div class=\"the_class\"><div class=\"inner_div\">foo</div>"
This malformed, but renderable HTML:
<div class="the_class"><div class="inner_div">foo
is even worse:
'<div class="the_class"><div class="inner_div">foo'[/<div class="the_class">(.*?)<\/div>/m]
=> nil
Whereas, a parser can deal with both:
require 'nokogiri'
[
'<div class="the_class"><div class="inner_div">foo</div></div>',
'<div class="the_class"><div class="inner_div">foo'
].each do |html|
doc = Nokogiri.HTML(html)
puts doc.at('div.the_class').text
end
Outputs:
foo
foo
Yes, your start and end strings could be anything, but there are well-recognized tools for parsing HTML/XML, and as your task grows the weaknesses in using regex will become more apparent.
And, yes, it's possible to have a parser fail. I've had to process RSS feeds that were so badly malformed the parser blew up, but a bit of pre-processing fixed the problem.
来源:https://stackoverflow.com/questions/13446059/ruby-regex-to-capture-everything-between-two-strings-inclusive