Regexp qui donne un =?iso-8859-1?q?r=E9sultat_diff=E9rent_da

Bonjour tout le monde,

Mon appli scanne des pages web à la recherche de liens vers des vidéos.
J’ai donc quelque chose qui ressemble à ceci:

open(@url) { |page|
  page_content = page.read()

page_content.scan(/href\s*=\s*[\"']([^\"']+)\.(wmv|avi|mpeg|mpg|mov|mp4)[\"']>(.+)<\/a>/i).each
{ |a|
    video_filename = a[0] + "." + a[1]
    link_content = a[2] # (attention: le contenu peut comprendre des
balises HTML, par ex <img ...>)
    # (... traitements ...)
  }
}

J’ai constaté un premier problème avec ce pattern. Si j’ai du code HTML
de ce genre, ça ne prend pas:

<a href="01.mov">
    <img src="01_screenshot.jpg" /></a>

Le problème provient du passage à la ligne entre le lien et son contenu
(ici une ). Le morceau de pattern “(.+)” ne prend pas en compte les
newlines. Pour faire simple, j’ai alors décidé de d’abord nettoyer la
source HTML en remplaçant les linebreaks:

page_content = page_content.tr("\n\r|\n|\r", "")

J’ai cru que mon problème serait résolu. Mais un (nouveau) problème est
apparu. Imaginons un code HTML de ce type:

<a href="01.mov"><img src="01_screenshot.jpg" /></a><a
href="02.mov"><img src="02_screenshot.jpg" /></a><a
href="03.mov"><img src="03_screenshot.jpg" /></a>

Le pattern ne prend pas bien et me renvoie un tableau avec ce résultat:

a[0] = "01"
a[1] = "wmv"
a[2] = <img src="01_screenshot.jpg" /></a><a href="02.mov"><img
src="02_screenshot.jpg" /></a><a href="03.mov"><img
src="03_screenshot.jpg" />

Alors que ce que je souhaite en a[2], c’est:

a[2] = <img src="01_screenshot.jpg" />

Ce qui est étrange, c’est que quand je teste mon pattern avec le code
HTML cité ci-dessus sur Regular Expression Library, le résultat est
celui souhaité. Mais dans mon appli Rails, le résultat n’est pas celui
souhaité.

Avez-vous une idée, une solution à mon problème?

Bonne journée,

Michael

Le Mar 5 décembre 2006 12:36, Michael H. a écrit :

page_content.scan(/href\s*=\s*[\"']([^\"']+)\.(wmv|avi|mpeg|mpg|mov|mp4)[\"']>(.+)<\/a>/i).each
src="03_screenshot.jpg" />

Les expressions rationnelles sont dites “gourmandes” par défaut. Le “.+”
c’est “un caractère, n’importe lequel, autant de fois que possible”. Du
coup, si tu vérifies, ce qu’il te sort correspond bel et bien à ce que tu
lui demandes. Il t’a trouvé un , un truc au milieu, et un
à la fin.

Si tu veux que ton “.+” capture le strict minimum, c’est à toi de l’en
informer. Changes ton “.+” par un “.+?”, et ça devrait faire ce que tu
souhaites.


Eric D.

De mémoire c’est l’option m pour que le point capture également le
retour à la ligne. J’évite d’utiliser ce joker car on a souvent des
mauvaises suprises. En effet elles sont gourmandes comme le dit Eric.
Je préciserai plutot tout ce qui ne correspond pas à ‘’. Ainsi tu
es sur de t’arrêter à la première balise :slight_smile:

à +

Le 05/12/06, Eric D.[email protected] a écrit :

Eric D. a écrit :

Le pattern ne prend pas bien et me renvoie un tableau avec ce résultat:

Si tu veux que ton “.+” capture le strict minimum, c’est à toi de l’en
informer. Changes ton “.+” par un “.+?”, et ça devrait faire ce que tu
souhaites.

Fantastique, c’est tout bon. Mon sauveur! :slight_smile:

Au passage, j’apprends donc l’usage du ‘?’ dans les expressions
régulières: “0 or 1 of previous expression; forces minimal matching when
an expression might match several strings within a search string”.

Michael

Bonjour Michael

Mon appli scanne des pages web à la recherche de liens vers des vidéos.

Avez-vous une idée, une solution à mon problème?

J’ai vu que tu as déjà une solution mais je fais quand même une
suggestion:
prend quelques instants pour voir ce que
hpricothttp://code.whytheluckystiff.net/hpricot/sait faire (
Hpricot is a very flexible HTML parser).
Je m’en sers pour faire de l’extraction de liens et j’en suis (très)
content, il fait ça beaucoup mieux que mes expressions régulières à moi.

Une deuxième suggestion si tu décides de conserver les expressions
régulières : les placer sous tests unitaires - ça permet de les mettre
au
point et d’éviter les régressions, vu qu’il est très facile de faire
claquer
une regexp sans s’en rendre compte…

a+

Thibaut Barrère