Мне нужно извлечь строку, которая начинается с тега <span class="style530">
и заканчивается </span>
тегом.
Я использовал команду sed, но не получил желаемого результата. Ниже приведен пример кода:
<strong>
-
<span class="style530">
AA -
This
is my
First
Heading</span></strong><br>
<span class="style530">
<strong>
*Some
text,*
<strong>
*text*</strong>,
*text*
<strong>
*text*</strong>:
<br>
<span class="style530">
<strong>
- This
is my
Second Heading</strong></span><br>
<span class="style530">
<strong>
*Some
text,*
<strong>
*text*</strong>,
*Here
is some
text.*
<strong>*text*</strong>:
*Here is
some
text*.<br>
<br>
<strong>
-
<span class="style530">
- This is
my Third
Heading</span></strong><br>
Вывод должен быть таким:
AA - This is my First Heading
- This is my Second Heading
- This is my Third Heading
Спасибо!
решение1
Regex на самом деле не способен полностью анализировать HTML.
Существует инструмент командной строки, который называетсяксиделькоторый позволяет использовать селекторы XPath или CSS для извлечения нужных фрагментов.
Что-то вроде этого будет соответствовать вашим требованиям:
./xidel test.html --extract '//span[@class="style530"]' --output-format bash
Но учтите, что это возвращает больше, чем требуется, так как у вас есть один незакрытый<span class="style530">
решение2
Используйте HTMLParser для таких действий:
#!/usr/bin/python
# vim: set fileencoding=utf8 :
# (c) fazie
from HTMLParser import HTMLParser
import re
import sys
class MyParser(HTMLParser):
inside_span = False
def __init__(self,file):
HTMLParser.__init__(self)
f = open(file)
self.feed(f.read())
def handle_starttag(self,tag,attrs):
if tag == 'span':
for name,value in attrs:
if name=='class' and value=='style530':
self.inside_span=True
def handle_data(self,data):
data = data.strip(' \t\r\n')
if data != "":
if self.inside_span:
data = re.sub('\n',' ',data)
data = re.sub('\s\s+',' ',data)
print data
def handle_endtag(self,tag):
if tag == 'span':
self.inside_span=False
MyParser(sys.argv[1])
Запустить его:
python myparser.py inputfile.html
решение3
Вы можете попробовать сделать что-то вроде этого.
awk -vRS='<' '
inside || /^span[^>]*class="style530"/ {
inside = 1
if (/^span/)
n++
else if (/^\/span>/ && !--n) {
$0="/span>\n"
inside=0
}
printf "<%s", $0
}' file.html | sed '/^</ d' | grep -v ">$"
Однако не рекомендуется извлекать с помощью заголовков HTML. Пожалуйста, см.здесьдля того, почему вам не следует парсить HTML-страницы. Я бы посоветовал вам использовать curl
и w3m
удалить заголовки HTML, после чего парсинг станет немного проще.
решение4
Для простого извлечения из текстов xml/html я предпочитаю использовать xidel сCSS-селекторы.
В этом примере, чтобы выбрать все span
элементы с атрибутом, class
содержащим слово style530
, мы можем использовать
xidel --css span.style530 --xml
xidel
имеет много вариантов. Ввод, предоставленный вопросом, немного шумный. В менее шумных ситуациях, с --xml
мы можем получить что-то вроде
<xml>
<span class="style530">case 1 </span>
<span class="menu style530 otherclass">case 2 </span>
...
</xml>