Comment entrer une expression régulière dans string.replace?

317

J'ai besoin d'aide pour déclarer une expression régulière. Mes entrées sont les suivantes:

this is a paragraph with<[1> in between</[1> and then there are cases ... where the<[99> number ranges from 1-100</[99>. 
and there are many other lines in the txt files
with<[3> such tags </[3>

La sortie requise est:

this is a paragraph with in between and then there are cases ... where the number ranges from 1-100. 
and there are many other lines in the txt files
with such tags

J'ai essayé ça:

#!/usr/bin/python
import os, sys, re, glob
for infile in glob.glob(os.path.join(os.getcwd(), '*.txt')):
    for line in reader: 
        line2 = line.replace('<[1> ', '')
        line = line2.replace('</[1> ', '')
        line2 = line.replace('<[1>', '')
        line = line2.replace('</[1>', '')

        print line

J'ai également essayé ceci (mais il semble que j'utilise la mauvaise syntaxe regex):

    line2 = line.replace('<[*> ', '')
    line = line2.replace('</[*> ', '')
    line2 = line.replace('<[*>', '')
    line = line2.replace('</[*>', '')

Je ne veux pas coder en dur le replace1 à 99. . .

alvas
la source
4
La réponse acceptée couvre déjà votre problème et le résout. As-tu besoin d'autre chose ?
HamZa
Quel devrait être le résultat where the<[99> number ranges from 1-100</[100>?
utapyngo
il devrait également supprimer le numéro dans la <...>balise, donc la sortie devrait êtrewhere the number rangers from 1-100 ?
alvas

Réponses:

566

Cet extrait testé devrait le faire:

import re
line = re.sub(r"</?\[\d+>", "", line)

Edit: Voici une version commentée expliquant comment cela fonctionne:

line = re.sub(r"""
  (?x) # Use free-spacing mode.
  <    # Match a literal '<'
  /?   # Optionally match a '/'
  \[   # Match a literal '['
  \d+  # Match one or more digits
  >    # Match a literal '>'
  """, "", line)

Les regex sont amusants! Mais je recommanderais fortement de passer une heure ou deux à étudier les bases. Pour commencer, vous devez savoir quels caractères sont spéciaux: les "métacaractères" qui doivent être échappés (c'est-à-dire avec une barre oblique inverse placée devant - et les règles sont différentes à l'intérieur et à l'extérieur des classes de caractères.) Il existe un excellent tutoriel en ligne sur: www .regular-expressions.info . Le temps que vous y passerez sera amorti plusieurs fois. Regexing heureux!

ridgerunner
la source
oui ça marche !! merci mais pouvez-vous expliquer le regex en bref?
alvas
9
Ne négligez pas non plus le livre sur les expressions régulières - Maîtriser les expressions régulières , par Jeffrey Friedl
pcurry
Une autre bonne référence voit w3schools.com/python/python_regex.asp
Carson
38

str.replace()fait des remplacements fixes. Utilisez re.sub()plutôt.

Ignacio Vazquez-Abrams
la source
3
Il convient également de noter que votre modèle doit ressembler à quelque chose comme "</ {0-1} \ d {1-2}>" ou à toute variante de notation regexp utilisée par python.
3
Que signifient les remplacements fixes?
avi
@avi Il voulait probablement dire un remplacement de mot fixe plutôt qu'un repérage partiel de mot par l'expression régulière.
Gunay Anach
chaînes fixes (littérales, constantes)
vstepaniuk
23

J'irais comme ça (regex expliqué dans les commentaires):

import re

# If you need to use the regex more than once it is suggested to compile it.
pattern = re.compile(r"</{0,}\[\d+>")

# <\/{0,}\[\d+>
# 
# Match the character “<” literally «<»
# Match the character “/” literally «\/{0,}»
#    Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «{0,}»
# Match the character “[” literally «\[»
# Match a single digit 0..9 «\d+»
#    Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
# Match the character “>” literally «>»

subject = """this is a paragraph with<[1> in between</[1> and then there are cases ... where the<[99> number ranges from 1-100</[99>. 
and there are many other lines in the txt files
with<[3> such tags </[3>"""

result = pattern.sub("", subject)

print(result)

Si vous voulez en savoir plus sur l' expression régulière, je vous recommande de lire le livre de recettes d'expressions régulières de Jan Goyvaerts et Steven Levithan.

Lorenzo Persichetti
la source
2
Vous pouvez simplement utiliser *au lieu de{0,}
HamZa
3
À partir des documents python : {0,}est le même que *, {1,}est équivalent à +et {0,1}est le même que ?. Il vaut mieux l'utiliser *, +ou ?quand vous le pouvez, simplement parce qu'ils sont plus courts et plus faciles à lire.
winklerrr
15

La manière la plus simple

import re

txt='this is a paragraph with<[1> in between</[1> and then there are cases ... where the<[99> number ranges from 1-100</[99>.  and there are many other lines in the txt files with<[3> such tags </[3>'

out = re.sub("(<[^>]+>)", '', txt)
print out
Ezequiel Marquez
la source
Les parenthèses sont-elles vraiment nécessaires? Ce ne serait pas la même regex: <[^>]+>? Soit dit en passant: je pense que votre expression régulière correspondrait trop (par exemple quelque chose comme <html>)
winklerrr
10

La méthode replace des objets chaîne n'accepte pas les expressions régulières mais seulement les chaînes fixes (voir la documentation: http://docs.python.org/2/library/stdtypes.html#str.replace ).

Vous devez utiliser le remodule:

import re
newline= re.sub("<\/?\[[0-9]+>", "", line)
Zac
la source
4
Vous devriez utiliser à la \d+place de[0-9]+
winklerrr
3

ne pas utiliser d'expression régulière (pour votre exemple de chaîne)

>>> s
'this is a paragraph with<[1> in between</[1> and then there are cases ... where the<[99> number ranges from 1-100</[99>. \nand there are many other lines in the txt files\nwith<[3> such tags </[3>\n'

>>> for w in s.split(">"):
...   if "<" in w:
...      print w.split("<")[0]
...
this is a paragraph with
 in between
 and then there are cases ... where the
 number ranges from 1-100
.
and there are many other lines in the txt files
with
 such tags
kurumi
la source
3
import os, sys, re, glob

pattern = re.compile(r"\<\[\d\>")
replacementStringMatchesPattern = "<[1>"

for infile in glob.glob(os.path.join(os.getcwd(), '*.txt')):
   for line in reader: 
      retline =  pattern.sub(replacementStringMatchesPattern, "", line)         
      sys.stdout.write(retline)
      print (retline)
Abena Saulka
la source