У меня довольно длинный текст, содержащий некоторые строки, которые находятся внутри тегов HTML (в основном h1
и h2
). Мне нужно полностью удалить их, что означает, что мне нужен способ найти текст, который заключен в определенные теги HTML, а затем удалите их из исходного текста.
Я пытался использовать gsub
но не мог понять, как создать регулярное выражение или что-то, что имеет смысл.
Найти и удалить узлы легко:
require 'nokogiri'
doc = Nokogiri::HTML(<<EOT)
<html>
<body>
<h1>foo</h1>
<h2>bar</h2>
<p>This is some text</p>
</body>
</html>
EOT
doc.search('h1, h2').remove
puts doc.to_html
# >> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
# >> <html><body>
# >>
# >>
# >> <p>This is some text</p>
# >> </body></html>
Я использую search
с помощью селектора h1, h2
CSS h1, h2
который найдет все узлы <h1>
и <h2>
и вернет их как NodeSet. NodeSet подобен массиву; remove
просто шаги, которые NodeSet и удаляет все его элементы.
Если вы хотите заглянуть внутрь узлов в свой текст, немного расширьте код:
require 'nokogiri'
doc = Nokogiri::HTML(<<EOT)
<html>
<body>
<h1>foo</h1>
<h2>bar</h2>
<h1>baz</h1>
<p>This is some text</p>
</body>
</html>
EOT
doc.search('h1, h2').select{ |n| n.text[/\b(?:foo|bar)\b/] }.map(&:remove)
puts doc.to_html
# >> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
# >> <html><body>
# >>
# >>
# >> <h1>baz</h1>
# >> <p>This is some text</p>
# >> </body></html>
text
возвращает текстовое содержимое узла. /\b(?:foo|bar)\b/
выглядит в этом тексте для слов "foo"
или "bar"
. Это приводит к массиву, поэтому я не могу использовать метод remove
NodeSet. Вместо этого я могу передать его на map
, которая будет перебирать каждый узел, который был возвращен select
, и отправить Nokogiri :: Node.select. Это немного более запутанно, но попадает туда.
Селектора XPath могли заглянуть внутрь текста узла, чтобы заменить часть кода Ruby, но они были бы довольно уродливыми. Я предпочитаю держать его простым.
Вы не можете использовать regex
для разбора HTML
(см. " Открытые теги соответствия RegEx, кроме тегов XHTML с автономными тегами "). Возможно, вы захотите посмотреть на XML-парсинг, например Nokogiri:
require 'nokogiri'
doc = Nokogiri::HTML(my_html)
h1s = doc.css('h1').map(&:text)
h2s = doc.css('h2').map(&:text)
nokogiri
. Вы можете манипулировать разобранным HTML, удалять теги и т. Д.