2010-09-09 5 views
0

Je veux remplacer les symboles consécutifs juste un tel que;regex concernant les symboles dans les URLs

c'est un chien ???

à

c'est un chien?

J'utilise cependant

str = re.sub("([^\s\w])(\s*\1)+", "\\1",str) 

Je remarque que cela pourrait remplacer des symboles dans les urls qui pourraient se produire dans mon texte.

comme http://example.com/this--is-a-page.html

Quelqu'un peut-il me donner des conseils sur la façon de modifier mon regex?

+0

Que voulez-vous qu'il retourne pour "http://example.com/this--is-a-page.html"? –

+0

@Lukas idéalement je ne veux pas modifier l'url Mais pour d'autres cas comme "Bonjour ...." et "hé !!!!" je voudrais les réduire à "Bonjour" et "hé!" – goh

+0

Voulez-vous le faire juste à la fin comme re.sub ("\ s * ([^ \ s \ w]) \ 1 * $", "\\ 1", str) – mb14

Répondre

2

Vous voulez donc libérer la puissance des expressions régulières sur un langage irrégulier comme le HTML. Tout d'abord, cherchez SO pour "parse HTML avec regex" pour découvrir pourquoi cela pourrait ne pas être une bonne idée.

Considérez ensuite ce qui suit: Vous souhaitez remplacer les symboles en double dans le texte (probablement entré par l'utilisateur). Vous ne voulez pas les remplacer dans une URL. Comment pouvez-vous dire ce qu'est une URL? Ils ne commencent pas toujours par http - disons que ars.userfriendly.org peut être une URL suivie d'un chemin plus long contenant des symboles en double.

En outre, vous trouverez beaucoup de symboles en double que vous ne voulez certainement pas remplacer (pensez aux parenthèses imbriquées (comme ceci)), certains d'entre eux peut-être <script> sur la page sur laquelle vous travaillez (||, && etc. viennent à l'esprit.

Alors vous pourriez venir avec quelque chose comme

(?<!\b(?:ftp|http|mailto)\S+)([^\\|&/=()"'\w\s])(?:\s*\1)+ 

qui arrive à travailler sur le code source de cette page très, mais va sûrement échouer dans d'autres cas (par exemple si les URL ne commencent pas par ftp, http ou mailto). De plus, cela ne fonctionnera pas en Python car il utilise la répétition variable à l'intérieur de lookbehind. Dans l'ensemble, vous n'utiliserez probablement pas votre langage HTML avec un vrai analyseur, en localisant le corps du texte, en lui appliquant une regex et en l'écrivant.

EDIT:

OK, vous travaillez déjà sur le texte analysé, mais il peut encore contenir des URL.

Ensuite, essayez ce qui suit:

result = re.sub(
    r"""(?ix) # case-insensitive, verbose regex 

    # Either match a URL 
    # (protocol optional (if so, URL needs to start with www or ftp)) 
    (?P<URL>\b(?:(?:https?|ftp|file)://|www\.|ftp\.)[-A-Z0-9+&@#/%=~_|$?!:,.]*[A-Z0-9+&@#/%=~_|$]) 

    # or 
    | 

    # match repeated non-word characters 
    (?P<rpt>[^\s\w])(?:\s{0,100}(?P=rpt))+""", 

    # and replace with both captured groups (one will always be empty) 
    r"\g<URL>\g<rpt>", subject) 

Re-EDIT: Hm, Python selfs de la part (?:\s*(?P=rpt))+, estimant que le + n'a rien à répéter. On dirait un bug en Python (reproductible avec (.)(\s*\1)+ alors que (.)(\s?\1)+ fonctionne) ...

Re-Re-EDIT: Si je remplace le * avec {0,100}, le regex compile. Mais maintenant, Python se plaint d'un groupe inégalé. Évidemment, vous ne pouvez pas référencer un groupe dans un remplacement s'il n'a pas participé au match. J'abandonne ... :(

+0

+1 pour le dernier paragraphe. dire qu'il voulait utiliser une regex sur le HTML .... juste le * contenu du texte * partie du HTML;) Mais pour cela, vous avez raison. Il devra utiliser un analyseur HTML, enlever tout ce qui se trouve à l'intérieur de '' et d'autres choses qui ne devraient pas être touchées, puis analyser les entrailles avec son regex, ce qui * peut * poser des problèmes. Je pense que c'est plus un problème social ... comment pouvons-nous empêcher les gens de laisser des commentaires stupides partout sur nos sites? – mpen

+0

@ Mark, @ Tim, vous avez raison. En fait, j'ai utilisé un analyseur. Je travaille actuellement sur l'expression régulière sur le contenu lui-même. – goh