12
votes

Wildcard correspondant à une chaîne de la recherche de python Regex

Je pensais écrire un code rapide pour télécharger le nombre de "fans" une page Facebook.

Pour une raison quelconque, malgré un bon nombre d'itérations que j'ai essayées, je ne peux pas obtenir le code suivant Pour choisir le nombre de ventilateurs dans le HTML. Aucune des autres solutions que j'ai trouvées sur le Web ne correspond correctement à la regex dans ce cas. Il est certainement possible d'avoir des caractères génériques entre les deux bits correspondants?

Le texte que j'aimerais faire correspondre contre est " 6 des x fans x ", où x est un arbitraire Nombre de ventilateurs Une page a - je voudrais obtenir ce numéro.

Je pensais à interroger ces données par intermittence et à écrire dans un fichier, mais je ne suis pas encore entendu à cela. Je me demande également si cela se dirige dans la bonne direction, car le code semble assez enclenché. :) xxx


4 commentaires

ne semble pas fonctionner n'est pas une description problématique


Sidenote: vous devriez nommer 'lignes' 'ligne' '


Veuillez poster le texte que vous essayez de faire correspondre et (si possible) le résultat que vous attendez.


Ungreedy . *? est utile dans des cas comme celui-ci.


3 Réponses :


14
votes
import urllib
import re

fbhandle = urllib.urlopen('http://www.facebook.com/Microsoft')
pattern = "6 of(.*)fans" #this wild card doesnt appear to work?
compiled = re.compile(pattern)

ms = compiled.search(fbhandle.read())
print ms.group(1).strip()
fbhandle.close()
You needed to use re.search() instead. Using re.match() tries to match the pattern against the whole document, but really you're just trying to match a piece inside the document. The code above prints: 79,110. Of course, this will probably be a different number by the time it gets run by someone else.

3 commentaires

merci beaucoup - fonctionne très bien. Je ne suis pas sûr que je comprenne parfaitement la distinction, cependant - match () serait utilisé dans des cas où une sorte de Bool Eval était-elle réalisée sur une petite chaîne (ish)?


@EeAday: Bonne explication de la différence entre match et : AMK.ca/python/howto/regex/...


Le lien dans le commentaire ne fonctionne pas, je me demande quel est le diff entre la recherche et le match.



0
votes

pas besoin de regex xxx

sortie xxx


0 commentaires

14
votes

Evan Fosmark a déjà donné une bonne réponse. C'est juste plus d'informations.

Vous avez cette ligne: xxx

en général, ce n'est pas une bonne expression régulière. Si le texte d'entrée était:

"6 sur 99 ventilateurs dans toute la galaxie des ventilateurs"

alors le groupe de correspondance (la matière à l'intérieur des parenthèses) serait:

"99 fans dans toute la galaxie de"

Donc, nous voulons un motif qui prendra simplement ce que vous voulez, même avec un texte d'entrée idiot comme ci-dessus.

Dans ce cas, peu importe que si vous faites correspondre à l'espace blanc, car lorsque vous convertissez une chaîne en un entier, l'espace blanc est ignoré. Mais écrivons le motif pour ignorer l'espace blanc.

avec la carte générique * , il est possible de faire correspondre une chaîne de longueur zéro. Dans ce cas, je pense que vous voulez toujours une correspondance non vide, vous souhaitez donc utiliser + pour correspondre à un ou plusieurs caractères.

Python a une correspondance non gourmande disponible, donc Vous pouvez réécrire avec ça. Les programmes plus anciens avec des expressions régulières peuvent ne pas avoir de correspondance non gourmande, donc je vais également donner un modèle qui ne nécessite pas non gourmandeux.

Donc, le motif non gourmand: < pré> xxx

l'autre: xxx

\ s signifie "n'importe quel espace blanc" et correspondra à un espace, un onglet et quelques autres caractères (tels que «Form Feed»). \ s signifie "tout espace de non-blanc" et correspond à tout ce que \ s serait pas match.

Le Le premier modèle fait mieux que votre premier motif avec le texte d'entrée idiot:

"6 de 99 fans de 99 dans toute la galaxie des fans"

Il retournerait un groupe de correspondance de juste 99 .

mais essayez cet autre texte d'entrée stupide:

"6 sur 99 fans folles"

Il retournerait un groupe de match de 99 Crazed .

Le deuxième modèle ne correspondrait pas du tout, car le mot "folie" n'est pas le mot "fans".

hmm. Voici un dernier modèle qui devrait toujours faire la bonne chose même avec des textes d'entrée idiotes: xxx

\ d correspond à n'importe quel chiffre ( '0 ' à ' 9 '). \ d correspond à tout autre chiffre.

Ceci correspondra avec succès tout ce qui est non ambiguë non ambigu:

"6 de 99 fans de l'ensemble de la galaxie des fans "

Le groupe de correspondance sera 99 .

" 6 sur 99 fans folles "

Le groupe de match sera 99 .

"6 sur 99 41 fans"

Il ne correspondra pas, car il y avait un deuxième numéro là-bas.

Pour en savoir plus sur les expressions régulières Python, vous pouvez lire Divers Web Pages . Pour un rappel rapide, à l'intérieur de l'interprète Python, faites: xxx

lorsque vous êtes "racler" du texte à partir d'une page Web, vous pouvez parfois exécuter des codes HTML. En général, les expressions régulières ne sont pas un bon outil pour ignorer le marquage HTML ou XML (voir ici ); Vous feriez probablement mieux d'utiliser belle soupe pour analyser le code HTML et extraire le texte, suivi de Une expression régulière pour attraper le texte que vous vouliez vraiment.

J'espère que c'était intéressant et / ou éducatif.


0 commentaires