Je suis actuellement à la recherche d'un moyen d'effectuer des correspondances de motifs via une expression régulière au début d'un nom de classe HTML. Le modèle que j'essaie de faire correspondre est:
regex = re.compile('^col-xs-.*$') soup.find_all("div", class_ = regex)
Deux exemples de classes dans la page HTML sont:
<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">
Le but est de ne correspond qu'au nom de classe ci-dessus, car il commence en fait par "col-xs -. *", ce que je recherche. En utilisant ma correspondance regex actuelle, je n'arrive pas à distinguer ces noms de classe. Actuellement, j'essaie de faire correspondre le modèle d'expression régulière suivant:
"col-xs-.*"
Malheureusement, ce modèle imprime également le nom de la deuxième classe (où "col-xs -. *" Apparaît dans au milieu et pas seulement au début). Espérons que quelqu'un a une solution à ce problème.
3 Réponses :
Je suppose que cette expression pourrait probablement extraire ces classes souhaitées:
['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']
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))
L'expression est expliquée sur le panneau supérieur droit de regex101.com , si vous souhaitez l'explorer / le simplifier / le modifier, et dans ce lien , vous pouvez voir comment il correspondrait à certains exemples d'entrées, si vous le souhaitez.
Je pense que vous voulez attribute = value sélecteur css l'opérateur avec commence par ^ pour spécifier la chaîne de préfixe à rechercher dans l'attribut de classe.
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)
Exemple:
soup.select('[class^="col-xs-"]')
Si vous voulez les trouver sans superbes supe, voici la façon de le faire.
Toutes les balises div avec un attribut de classe où col-xs-
est au début de la valeur:
Inclut le rognage des espaces.
(?i) < div (?= (?: [^>"'] | " [^"]* " | ' [^']* ' )*? (?<= \s ) class \s* = \s* (?: ( ['"] ) # (1) \s* ( # (2 start) col-xs- (?: (?! \1 ) [\S\s] )*? ) # (2 end) \s* \1 ) ) \s+ (?: " \S\s ]*? " | ' \S\s ]*? ' | [^>]*? )+ >
https://regex101.com/r / rsXqI9 / 1
Formaté:
La valeur de la classe est dans le groupe 2.
r"(?i)<div(?=(?:[^>\"']|\"[^\"]*\"|'[^']*')*?(?<=\s)class\s*=\s*(?:(['\"])\s*(col-xs-(?:(?!\1)[\S\s])*?)\s*\1))\s+(?:\"\S\s]*?\"|'\S\s]*?'|[^>]*?)+>"
Le
. *
correspond jusqu'à la fin de la chaîne. Essayez\ bcol-xs- \ d + \ b
@Thefourthbird Votre solution ne semble malheureusement pas fonctionner. Et est-ce important que le. * Corresponde jusqu'à la fin de la chaîne? Tout ce dont j'ai besoin, c'est que le motif apparaisse au début de la chaîne, le reste qui se passe après n'est pas vraiment si important que je pense.