2009-05-14 7 views
1

J'ai un tas de HTML avec des lignes comme ceci:espaces match Regex dans l'attribut html

<a href="#" rel="this is a test">

Je dois remplacer les espaces dans l'attribut rel avec underscores, mais je suis une sorte de regex-noob!

J'utilise Textmate.

Quelqu'un peut-il m'aider?

/Jakob

+0

Ce n'est pas facile avec un éditeur de texte qui ne permet que la recherche et le remplacement. C'est parce que vous avez besoin d'un modèle pour trouver le bon endroit (attribut rel) et ensuite vous avez besoin d'un modèle à remplacer. –

+0

J'espérais trouver une solution avec une regex dans une autre regex (si cela a du sens). Parce que vous avez raison, ce match est en quelque sorte une solution en deux passes. Trouve d'abord la chaîne: (rel = ". *") Puis remplace tous les espaces par (_). Peut-être que ce n'est tout simplement pas possible? –

+0

@Jakob Madsen Votre désir de récursion est exactement exact, et à l'utilisation de certaines extensions Perl, les regex ne peuvent pas se reproduire. C'est l'une des raisons pour lesquelles les regex sont mauvaises lors de l'analyse HTML et XML. Vous avez besoin d'un analyseur. –

Répondre

0

Je ne pense pas que vous pouvez le faire correctement. Bien que je me demande pourquoi vous devez le faire en une fois?

je peux penser à une façon vraiment pauvre de le faire, mais même si je ne le recommande pas, va ici:

Vous pouvez sorte de le faire avec l'expression rationnelle ci-dessous. Cependant, vous devrez augmenter le nombre de captures et de sorties avec un _ à la fin du nombre potentiel d'espaces dans le rel. Je parie que c'est une exigence qui interdit cette solution.

Recherche:

{\<a *href\=\"[^\"]*" *rel\=\"}{([^ ]*|[^\"]*)}(|\")*{([^ ]*|[^\"]*)}(|\")*{([^ ]*|[^\"]*)}(|\")*{([^ ]*|[^\"]*)}(|\")*{([^ ]*|[^\"]*)}(|\")*{([^ ]*|[^\"]*)}(|\")*{([^ ]*|[^\"]*)}(|\")*{([^ ]*|[^\"]*)}(|\")* 

Remplacer:

\1\2_\3_\4_\5_\6_\7_\8_ 

De cette façon, a deux inconvénients, on est qu'il pourrait y avoir des limites au nombre de captures que vous pouvez avoir dans TextMate, deux est que vous aurez finir avec un grand nombre de _ à la fin de chaque ligne.

Avec votre test en cours, avec l'expression rationnelle ci-dessus, vous finiriez avec:

<a href="#" rel="this_is_a_test">____ 

PS: Ce regex est du format de la recherche de Visual Studio/remplacer boîte. Vous aurez probablement besoin de changer certains caractères pour l'adapter au texte.

{} => capturing group 

() => grouping 

    [^A] => anything but A 

    (|\")* => space or " 

    \1 => is the first capture 
+0

Salut merci! Vous m'avez donné quelque chose à penser. Vous avez absolument raison. Je n'ai pas besoin de le faire en une fois. J'ai trouvé un moyen de faire correspondre le premier espace, bien qu'il ressemble un peu à une blague: (? <= Rel = "[\ w +] [\ w +] [\ w +] [\ w +]) \ s + (-: Quoi qu'il en soit je reçois: Je pense que je devrais être en mesure de lancer la recherche/remplacer plusieurs fois jusqu'à ce qu'il cesse de se . matchs en fait de remplacer les espaces un à la fois: Q: Comment éviter les répétitions [\ w +]? Est-ce que cela correspondra au _? –

+0

Wow, le commentaire a mangé mes nouvelles lignes ... Espérons que c'est encore lisible! –

0

Je dois me rendre à bord du train «Vous utilisez le mauvais outil pour le travail» ici. Vous avez Textmate, ce qui signifie OSX, ce qui signifie que vous avez sed, awk, ruby ​​et perl qui peuvent tous faire beaucoup mieux et plus facilement. L'apprentissage de l'utilisation de l'un de ces outils pour manipuler du texte vous apportera d'innombrables avantages à l'avenir. Voici une URL qui va vous faciliter la vie: http://www.grymoire.com/Unix/Sed.html

-1

Si vous utilisez TextMate, alors vous êtes sur un Mac, et avez donc Python.

Essayez ceci:

#!/usr/bin/env python 

import re 

input = open('test.html', 'r') 

p_spaces = re.compile(r'^.*rel="[^"]+".*$') 

for line in input: 
    matches = p_spaces.findall(line) 

    for match in matches: 
     new_rel = match.replace(' ', '_') 
     line = line.replace(match, new_rel) 

    print line, 

Exemple de sortie:

$ cat test.html 
testing, testing, 1, 2, 3 
<a href="#" rel="this is a test"> 
<unrelated line> 
Stuff 
<a href="#" rel="this is not a test"> 
<a href="#" rel="this is not a test" rel="this is invalid syntax (two rels)"> 
aoseuaoeua 

$ ./test.py 
testing, testing, 1, 2, 3 
<a_href="#"_rel="this_is_a_test"> 
<unrelated line> 
Stuff 
<a_href="#"_rel="this_is_not_a_test"> 
<a_href="#"_rel="this_is_not_a_test"_rel="this_is_invalid_syntax_(two_rels)"> 
aoseuaoeua 
+0

Ceci remplace les espaces blancs dans toute la ligne, pas seulement dans l'attribut. – problemofficer

0

Recherche: (rel="[^\s"]*)\s([^"]*")

Remplacer: \1_\2

Ce ne remplace que le premier espace blanc pour cliquer sur « Remplacer Tout "jusqu'à ce que rien ne soit remplacé nymore. Ce n'est pas joli mais facile à comprendre et fonctionne avec tous les éditeurs.

Modifiez rel dans le modèle de recherche si vous devez nettoyer d'autres attributs.