RegEx для извлечения конкретного textContent в тегах HTML - PullRequest
5 голосов
/ 20 мая 2019

Мне нужно создать программу на Python, которая получает HTML-файл со стандартного ввода и выводит названия видов, отображаемых под заголовком Млекопитающие, на стандартный вывод построчно, используя регулярное выражение.Мне также не нужно выводить элемент, отображаемый как «#sequence_only».

Файл, используемый для стандартного ввода, таков:

   <!DOCTYPE html>

  <!-- The following setting enables collapsible lists -->
  <p>
  <a href="#human">Human</a></p>

  <p class="collapse-section">
  <a class="collapsed collapse-toggle" data-toggle="collapse" 
  href=#mammals>Mammals</a>
  <div class="collapse" id="mammals">
  <ul>
  <li><a href="#alpaca">Alpaca</a>
  <li><a href="#armadillo">Armadillo</a>
  <li><a href="#sequence_only">Armadillo</a> (sequence only)
  <li><a href="#baboon">Baboon</a>
  <li><a href="#bison">Bison</a>
  <li><a href="#bonobo">Bonobo</a>
  <li><a href="#brown_kiwi">Brown kiwi</a>
  <li><a href="#bushbaby">Bushbaby</a>
  <li><a href="#sequence_only">Bushbaby</a> (sequence only)
  <li><a href="#cat">Cat</a>
  <li><a href="#chimp">Chimpanzee</a>
  <li><a href="#chinese_hamster">Chinese hamster</a>
  <li><a href="#chinese_pangolin">Chinese pangolin</a>
  <li><a href="#cow">Cow</a>
  <li><a href="#crab-eating_macaque">Crab-eating_macaque</a>
  <div class="gbFooterCopyright">
  &copy; 2017 The Regents of the University of California. All 
  Rights Reserved.
  <br>
  <a href="https://genome.ucsc.edu/conditions.html">Conditions of 
  Use</a>
  </div>

Моя логика следующая.Я хочу разобрать значение href.Если строка начинается с

, а значение href начинается с "#" -> это имя вида, и мне нужно извлечь имя между "> <символами. Если значение href начинается с" https ", яхочу добавить его другим символом и не вводить в окончательном выводе. </p>

Я пытался создать регулярное выражение для извлечения имени млекопитающего.

#!usr/bin/env python3

import sys
import re

html = sys.stdin.readlines()

for line in html:

    mammal_name = re.search(r'\"\>(.*?)\<', line)

if mammal_name:

    print(mammal_name.group())

Я хотел получить вывод, например:

Alpaca
Armadillo
Baboon

Я получил выходные данные, такие как:

">Human<
">Alpaca<
">Armadillo<
">Armadillo<
">Baboon<

Я не хочу, чтобы Human был в выводе, поскольку строка, в которой он находится, не начинается с

. Более того, я делаюЯ не хочу повторений в моем выводе, но для этого мне нужно получить доступ к значению href, но я борюсь с этой частью.

ОБНОВЛЕНИЕ : Мой грейдер показывает мне следующее сообщение: «Если вызаключите название вида в теги, оно будет отображаться курсивом во многих браузерах, поэтому сотрудники, которые хотели отображать научные названия курсивом, вероятно, использовали теги.В любом случае, оно неуместно в качестве названия вида, поэтому, пожалуйста, удалите его ". Я предполагаю, что речь идет о> (названии вида) <, поэтому мне нужно заменить> <между названием вида с каким-либо другим символом, вероятно, []и делать анализ моего регулярного выражения после этого ?? </p>

Ответы [ 4 ]

2 голосов
/ 20 мая 2019

Здесь мы просто хотим добавить две левые (<li><a.+?>) и правые границы (<\/.+>), затем проведите по нашим желаемым выводам и сохраните их в $1 группе захвата ():

<li><a.+?>(.+)?<\/.+>

Тест

# -*- coding: UTF-8 -*-
import re

string = """
!-- The following setting enables collapsible lists -->
  <p>
  <a href="#human">Human</a></p>

  <p class="collapse-section">
  <a class="collapsed collapse-toggle" data-toggle="collapse" 
  href=#mammals>Mammals</a>
  <div class="collapse" id="mammals">
  <ul>
  <li><a href="#alpaca">Alpaca</a>
  <li><a href="#armadillo">Armadillo</a>
  <li><a href="#sequence_only">Armadillo</a> (sequence only)
  <li><a href="#baboon">Baboon</a>
  <li><a href="#bison">Bison</a>
  <li><a href="#bonobo">Bonobo</a>
  <li><a href="#brown_kiwi">Brown kiwi</a>
  <li><a href="#bushbaby">Bushbaby</a>
  <li><a href="#sequence_only">Bushbaby</a> (sequence only)
  <li><a href="#cat">Cat</a>
  <li><a href="#chimp">Chimpanzee</a>
  <li><a href="#chinese_hamster">Chinese hamster</a>
  <li><a href="#chinese_pangolin">Chinese pangolin</a>
  <li><a href="#cow">Cow</a>
  <li><a href="#crab-eating_macaque">Crab-eating_macaque</a>
  <div class="gbFooterCopyright">
  &copy; 2017 The Regents of the University of California. All 
  Rights Reserved.
  <br>
  <a href="https://genome.ucsc.edu/conditions.html">Conditions of 
  Use</a>
  </div>
"""
expression = r'<li><a.+?>(.+)?<\/.+>'
match = re.search(expression, string)
if match:
    print("YAAAY! \"" + match.group(1) + "\" is a match ??? ")
else: 
    print('? Sorry! No matches!')

Выход

YAAAY! "Alpaca" is a match ??? 

RegEx

Если это выражение нежелательно, его можно изменить или изменить в regex101.com .

enter image description here

RegEx Circuit

jex.im также помогает визуализировать выражения.

enter image description here


Редактировать:

Чтобы исключить sequence_only, мы можем изменить наше выражение на:

<li.+?#[^s].+?>(.+)?<\/.+>

Демо

Python

# coding=utf8
# the above tag defines encoding for this document and is for Python 2.x compatibility

import re

test_str = '''

<!DOCTYPE html>

  <!-- The following setting enables collapsible lists -->
  <p>
  <a href="#human">Human</a></p>

  <p class="collapse-section">
  <a class="collapsed collapse-toggle" data-toggle="collapse" 
  href=#mammals>Mammals</a>
  <div class="collapse" id="mammals">
  <ul>
  <li><a href="#alpaca">Alpaca</a>
  <li><a href="#armadillo">Armadillo</a>
  <li><a href="#sequence_only">Armadillo</a> (sequence only)
  <li><a href="#baboon">Baboon</a>
  <li><a href="#bison">Bison</a>
  <li><a href="#bonobo">Bonobo</a>
  <li><a href="#brown_kiwi">Brown kiwi</a>
  <li><a href="#bushbaby">Bushbaby</a>
  <li><a href="#sequence_only">Bushbaby</a> (sequence only)
  <li><a href="#cat">Cat</a>
  <li><a href="#chimp">Chimpanzee</a>
  <li><a href="#chinese_hamster">Chinese hamster</a>
  <li><a href="#chinese_pangolin">Chinese pangolin</a>
  <li><a href="#cow">Cow</a>
  <li><a href="#crab-eating_macaque">Crab-eating_macaque</a>
  <div class="gbFooterCopyright">
  &copy; 2017 The Regents of the University of California. All 
  Rights Reserved.
  <br>
  <a href="https://genome.ucsc.edu/conditions.html">Conditions of 
  Use</a>
  </div>

'''
regex = r"<li.+?#[^s].+?>(.+)?<\/.+>"
find_matches = re.findall(regex, test_str)
for matches in find_matches:
    print(matches)

Выход

Alpaca
Armadillo
Baboon
Bison
Bonobo
Brown kiwi
Bushbaby
Cat
Chimpanzee
Chinese hamster
Chinese pangolin
Cow
Crab-eating_macaque
1 голос
/ 20 мая 2019

Используйте BeautifulSoup, это мощный пакет для разбора html:

import re
import codecs

from bs4 import BeautifulSoup as soup
from lxml import html

# Change with your input file 
input_html = "D:\/input.html"

with codecs.open(input_html, 'r', "utf-8") as f :
    page = f.read()
f.close()
#html parsing
page_soup = soup(page, "html.parser")

#extract document seperator:
divTag = page_soup.find_all("div", {"id": "mammals"})

for tag in divTag:
    mammals = tag.find_all("a", href = re.compile(r'#(?!sequence_only$)'))
    for tag in mammals:
        print(tag.text)

Вывод:

Alpaca
Armadillo
Baboon
Bison
Bonobo
Brown kiwi
Bushbaby
Cat
Chimpanzee
Chinese hamster
Chinese pangolin
Cow
Crab-eating_macaque


0 голосов
/ 20 мая 2019

Вы должны добавить некоторые детали в свое регулярное выражение для анализа правильных строк. Тестовый веб-сайт Regex .

Ввод:

string = '''   <!DOCTYPE html>

  <!-- The following setting enables collapsible lists -->
  <p>
  <a href="#human">Human</a></p>

  <p class="collapse-section">
  <a class="collapsed collapse-toggle" data-toggle="collapse" 
  href=#mammals>Mammals</a>
  <div class="collapse" id="mammals">
  <ul>
  <li><a href="#alpaca">Alpaca</a>
  <li><a href="#armadillo">Armadillo</a>
  <li><a href="#sequence_only">Armadillo</a> (sequence only)
  <li><a href="#baboon">Baboon</a>
  <li><a href="#bison">Bison</a>
  <li><a href="#bonobo">Bonobo</a>
  <li><a href="#brown_kiwi">Brown kiwi</a>
  <li><a href="#bushbaby">Bushbaby</a>
  <li><a href="#sequence_only">Bushbaby</a> (sequence only)
  <li><a href="#cat">Cat</a>
  <li><a href="#chimp">Chimpanzee</a>
  <li><a href="#chinese_hamster">Chinese hamster</a>
  <li><a href="#chinese_pangolin">Chinese pangolin</a>
  <li><a href="#cow">Cow</a>
  <li><a href="#crab-eating_macaque">Crab-eating_macaque</a>
  <div class="gbFooterCopyright">
  &copy; 2017 The Regents of the University of California. All 
  Rights Reserved.
  <br>
  <a href="https://genome.ucsc.edu/conditions.html">Conditions of 
  Use</a>
  </div>'''

Если вы хотите обработать весь текст в одном выражении, вы должны использовать findall(). Код:

results = re.findall("<li><a href=\"(?:(?!#sequence_only).)*\">(.*)</a>", string)
for s in results:
    print(s)

Если вы хотите проверить это построчно, вы можете использовать search(). Код:

strings = string.splitlines()
for s in strings:
    substring = re.search("<li><a href=\"(?:(?!#sequence_only).)*\">(.*)</a>", s)
    if substring:
        print(substring.group(1))

Выход:

Alpaca
Armadillo
Baboon
Bison
Bonobo
Brown kiwi
Bushbaby
Cat
Chimpanzee
Chinese hamster
Chinese pangolin
Cow
Crab-eating_macaque
0 голосов
/ 20 мая 2019

используйте re.findall, чтобы получить все теги текстовый текст, как этот

pattern = r'<li><a.*>(.*)</a>'
find = re.findall(pattern, string)
if find:
    print(find)

out put

['Alpaca', 'Armadillo', 'Armadillo', 'Baboon', 'Bison', 'Bonobo', 'Brown kiwi', 
'Bushbaby', 'Bushbaby', 'Cat', 'Chimpanzee', 'Chinese hamster', 'Chinese pangolin', 
'Cow', 'Crab-eating_macaque']
...