Сопоставление шаблонов регулярных выражений в начале строки с помощью BeautifulSoup

В настоящее время я ищу способ выполнить сопоставление с образцом с помощью регулярного выражения в начале имени класса HTML. Шаблон, который я пытаюсь сопоставить:

"col-xs-.*"

Два примера классов на HTML-странице:

<div class="col-xs-12 col-sm-12 col-lg-12">
<div class="mod-tiles__sizer col-xs-6 col-sm-4 col-lg-3">

Цель состоит в том, чтобы сопоставить только указанное выше имя класса, так как оно фактически начинается с «col-xs-.*», что мне и нужно. Используя мое текущее сопоставление регулярных выражений, я не могу выделить эти имена классов. В настоящее время я пытаюсь сопоставить следующий шаблон регулярного выражения:

regex = re.compile('^col-xs-.*$')
soup.find_all("div", class_ = regex)

К сожалению, этот шаблон также выводит второе имя класса (где «col-xs-.*» появляется в середине, а не только в начале). Надеюсь, у кого-то есть решение этой проблемы.


person Menno Van Dijk    schedule 20.07.2019    source источник
comment
.* совпадает до конца строки. Попробуйте \bcol-xs-\d+\b   -  person The fourth bird    schedule 20.07.2019
comment
@Thefourthbird Ваше решение, к сожалению, не работает. И имеет ли значение, что .* совпадает до конца строки? Все, что мне нужно, это чтобы шаблон появлялся в начале строки, остальное, что происходит после, на самом деле не так важно, я думаю.   -  person Menno Van Dijk    schedule 20.07.2019


Ответы (3)


Я думаю, вам нужен attribute = value селектор css, начинающийся с ^, чтобы указать строку префикса, которую нужно найти в атрибуте класса.

soup.select('[class^="col-xs-"]')

Пример:

from bs4 import BeautifulSoup as bs

html = '''
<div class="col-xs-12 col-sm-12 col-lg-12">
<div class="mod-tiles__sizer col-xs-6 col-sm-4 col-lg-3">
'''
soup = bs(html, 'lxml')
classes = [' '.join(item['class']) for item in soup.select('[class^="col-xs-"]')]
print(classes)
person QHarr    schedule 20.07.2019

Я предполагаю, что это выражение, вероятно, может извлечь эти желаемые классы:

import re

regex = r"[\"']\s*(\bcol-xs-[0-9]+\b[^\"']+?)\s*[\"']"

test_str = """

<div class="col-xs-12 col-sm-12 col-lg-12"><div class="  col-xs-12 col-sm-12 col-lg-12  ">
<div class="mod-tiles__sizer col-xs-6 col-sm-4 col-lg-3"><div class="col-xs-12 col-sm-12 col-lg-12">
<div class="mod-tiles__sizer col-xs-6 col-sm-4 col-lg-3">

"""

print(re.findall(regex, test_str, re.MULTILINE | re.IGNORECASE))

Выход

['col-xs-12 col-sm-12 col-lg-12', 'col-xs-12 col-sm-12 col-lg-12', 'col-xs-12 col-sm-12 col-lg-12']

Выражение объясняется на верхней правой панели regex101.com, если вы хотите изучить/ упростите/измените его, а в этой ссылке вы можете посмотреть, как он будет соответствовать некоторому образцу входы, если хотите.

person Emma    schedule 20.07.2019

Если вы хотите найти их без красивого супера, это способ сделать это.
Все теги div с атрибутом класса, где col-xs- стоит в начале значения:

Включает обрезку пробелов.

r"(?i)<div(?=(?:[^>\"']|\"[^\"]*\"|'[^']*')*?(?<=\s)class\s*=\s*(?:(['\"])\s*(col-xs-(?:(?!\1)[\S\s])*?)\s*\1))\s+(?:\"\S\s]*?\"|'\S\s]*?'|[^>]*?)+>"

https://regex101.com/r/rsXqI9/1

Отформатировано:
Значение класса находится в группе 2.

 (?i)
 < div 
 (?=
      (?: [^>"'] | " [^"]* " | ' [^']* ' )*?
      (?<= \s )
      class \s* = \s* 
      (?:
           ( ['"] )                      # (1)
           \s* 
           (                             # (2 start)
                col-xs-

                (?:
                     (?! \1 )
                     [\S\s] 
                )*?
           )                             # (2 end)
           \s* 
           \1 
      )
 )
 \s+ 
 (?: " \S\s ]*? " | ' \S\s ]*? ' | [^>]*? )+
 >
person Community    schedule 20.07.2019