Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

[regexp] matcher un nom de domaine dans une URL

3 réponses
Avatar
Rakotomandimby (R12y) Mihamina
[ Xpost fcou fca + fu2 fca ]

Bonjour,

Soit un fichier contenant plusieurs urls

http://un.domaine.com/fd/sdffds/fffd.html ;
http://un.autre.domaine/dsdq.htm, ...

Il peut y en avoir plusieurs par ligne, des URLs, pas forcément
séparées par des "," ou des ";" ...

je souhaite trouver la _regexp_ qui matche le nom de domaine, de manière
a pouvoir extraire

un.domaine.com
un.autre.domaine


On cherche donc les occurences qui commencent par http:// et on s'arrete
au premier "/" rencontré, et on prend ce qu'il y a au milieu.

Euh.... en fait je ne me retrouve pas _du tout_.

Déjà, est-ce que les regexp sont ce qu'il me faut, ou il vaut mieux que
je fasse plutot un petit script (Perl, Python, Caml...) ou
carrément un petit proramme en C dédié à cela?

C'est pour traiter un "enorme" volume: Le fichier duquel il faut extraire
les noms de domaines fait environ 4Go, et il faudra faire ça une fois par
jour au moins, donc, investir dans un petit truc en "autre chose que des
regexp" est rentable... (énorme parceque la machine est un 275Mhz avec
32Mo de RAM)

Je suis sous Linux.

--
Les serveurs avec 10Mb/s se louent maintenant pour 50 ou 60 Euros par mois!
La preuve http://www.google.fr/search?q=serveur+dedie
Infogerance de serveur dedie http://aspo.rktmb.org/activites/infogerance
(En louant les services de l'ASPO vous luttez contre la fracture numerique)

3 réponses

Avatar
Nicolas George
Fabien LE LEZ wrote in message
Ce n'est pas si simple que ça !

<http://edulang.com/recherche.php?http://microsoft.com/> et
<http://edulang.com/recherche.php?;http://microsoft.com/> sont des URL
valides.


Ça, ce n'est pas un vrai problème, car on trouve le premier http://, et on
parse jusqu'à la fin de l'URL valide (comme décrite dans la RFC kivabien).
En revanche, <URL: x-foobar://somehost.tld/foo/http://some.other.host.tld/ >
est plus problématique, parce qu'on n'identifie pas le début de la vraie
URL. Mais selon le format du fichier, on peut assez facilement évacuer ce
problème.

À supposer que ce soit le cas, je vais proposer une implémentation qui
devrait être plutôt rapide, mais très dépendante du système, donc retour
dans fcou.

Il s'agit de chercher le prochain « http:// », pour ça, un KMP déroulé à la
main me semble le plus efficace. Donc (en C, évidemment, puisqu'on veut de
la vitesse) :

while(<condition de taille de fichier>) {
if(*(p++) == 'h') {
if(*p != 't')
continue;
if(*(++p) != 't')
continue;
if(*(++p) != 'p')
continue;
if(*(++p) != ':')
continue;
if(*(++p) != '/')
continue;
if(*(++p) != '/')
continue;
<la suite ici>
}
}

Quand tu arrives au commentaire, tu as p qui pointe vers le début du domaine
dans l'URL. Tu en prends une copie, de ce pointeur, évidemment. Il ne reste
plus qu'à tranquilement parcourir la chaîne tant que tu vois des caractères
valides pour un nom de domaine. Quand tu es au bout, tu as entre les deux
pointeurs est le domaine cherché. Ensuite, tu fais avancer p tant que tu as
des caractères valides dans une URL.

La question qui reste, c'est la lecture du fichier. Si tu as une archi
64 bits, la réponse est très simple : mmap complet du fichier et tu ne te
poses pas de question.

Sur une archi 32 bits, tu ne peux pas le faire. Je pense que le plus
efficace est dans ce cas de mmaper de gros bouts du fichiers (disons 512 Mo,
les détails importent peu car ce sera de toutes façons négligeable). Le truc
va être de re-mmaper la suite du fichier soit quand ton p arrive à la fin du
segment mmapé à la recherche d'un 'h', soit quand tu trouves un 'h' trop
près de la fin du segment.

Pour le premier, il faut une boucle englobante :

while(<toujours pas la fin du fichier>) {
<mmaper la suite du fichier>
fin = <début du mmap + taille du mmap>
p = <début du mmap>
while(p < fin) {
...
}
}

Pour le second, c'est un peu plus acrobatique, quelque chose comme :

if(fin - p < MAX_URL_SIZE) {
o = p - <début du mmap>;
<munmaper le fichier>
<mmaper le fichier un peu plus loin, avec un recouvrement convenable>
fin = <ce qu'il faut>
p = <nouveau début du mmap> + o - <avancée dans le fichier>;
<parcours de l'URL>
}

Le point important, si tu veux gagner de la vitesse, est de limiter au
maximum les endroits où tu dois tester que tu es bien dans les limites.

Avatar
Rakotomandimby (R12y) Mihamina
( Sat, 02 Apr 2005 12:19:17 +0000 ) Nicolas George :

Je pense que le plus
efficace est dans ce cas de mmaper de gros bouts du fichiers


Je vais donc me documenter sur le "mmapage", pour savoir ce que c'est,
déjà...

Merci.

--
Les serveurs avec 10Mb/s se louent maintenant pour 50 ou 60 Euros par mois!
La preuve http://www.google.fr/search?q=serveur+dedie
Infogerance de serveur dedie http://aspo.rktmb.org/activites/infogerance
(En louant les services de l'ASPO vous luttez contre la fracture numerique)

Avatar
Nicolas George
R12y wrote in message :
Je vais donc me documenter sur le "mmapage", pour savoir ce que c'est,
déjà...


Ça n'a rien de bien compliqué, ça revient à demander à l'OS de charger le
fichier en mémoire en faisant usage de la MMU : le fichier n'est pas chargé
immédiatement, mais quand un accès à la zone mémoire correspondante est
faite, par le même mécanisme qui permet de faire sortir du swap les bouts de
mémoire qui s'y étaient retrouvés. C'est plus efficace que de lire
manuellement le fichier dans un tampon, car il y a des copies en moins et
car le noyau gère plus efficacement ses politiques de cache.
Optionnellement, tu peux mmaper en écriture également, ce qui fait qu'une
modification en mémoire est reportée sur le fichier (instantanément plus le
cache).