¿Cómo ingresar una expresión regular en string.replace?

317

Necesito ayuda para declarar una expresión regular. Mis entradas son como las siguientes:

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 salida requerida es:

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

He intentado esto:

#!/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

También probé esto (pero parece que estoy usando la sintaxis de expresiones regulares incorrecta):

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

No quiero codificar el replace1 al 99. . .

alvas
fuente
44
La respuesta aceptada ya cubre su problema y lo resuelve. Necesitas algo más ?
HamZa
¿Cuál debería ser el resultado where the<[99> number ranges from 1-100</[100>?
utapyngo
también debería eliminar el número en la <...>etiqueta, por lo que el resultado debería serwhere the number rangers from 1-100 ?
alvas

Respuestas:

566

Este fragmento probado debería hacerlo:

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

Editar: Aquí hay una versión comentada que explica cómo funciona:

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)

¡Las expresiones regulares son divertidas! Pero recomendaría pasar una o dos horas estudiando los conceptos básicos. Para empezar, debes aprender qué personajes son especiales: "metacaracteres" que deben escaparse (es decir, con una barra invertida colocada al frente, y las reglas son diferentes dentro y fuera de las clases de caracteres). Hay un excelente tutorial en línea en: www .regular-expressions.info . El tiempo que pase allí se amortizará muchas veces. Feliz regexing!

ridgerunner
fuente
¡sí, funciona! gracias, pero ¿puedes explicar la expresión regular en breve?
alvas
99
Tampoco descuides El libro sobre expresiones regulares - Dominando las expresiones regulares , por Jeffrey Friedl
pcurry
Otra buena referencia ve w3schools.com/python/python_regex.asp
Carson
38

str.replace()hace reemplazos fijos. Usar en su re.sub()lugar.

Ignacio Vazquez-Abrams
fuente
3
También vale la pena señalar que su patrón debería verse como "</ {0-1} \ d {1-2}>" o cualquier variante de notación regexp que use python.
3
¿Qué significan los reemplazos fijos?
avi
@avi Probablemente se refería a la sustitución de palabras fijas en lugar de la localización parcial de palabras a través de expresiones regulares.
Gunay Anach
cadenas fijas (literales, constantes)
vstepaniuk
23

Me gustaría ir así (regex explicado en los comentarios):

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 desea obtener más información sobre la expresión regular, le recomiendo leer el Libro de cocina de expresiones regulares de Jan Goyvaerts y Steven Levithan.

Lorenzo Persichetti
fuente
2
Simplemente podría usar en *lugar de{0,}
HamZa
3
De los documentos de Python : {0,}es lo mismo que *, {1,}es equivalente a +, y {0,1}es lo mismo que ?. Es mejor usar *, +o ?cuando puedes, simplemente porque son más cortos y fáciles de leer.
winklerrr
15

La forma más fácil

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
fuente
¿Son realmente necesarios los paréntesis? ¿No sería la misma expresión regular <[^>]+>? Por cierto: creo que su expresión regular coincidiría demasiado (por ejemplo, algo así como <html>)
winklerrr
10

El método de reemplazo de objetos de cadena no acepta expresiones regulares sino solo cadenas fijas (consulte la documentación: http://docs.python.org/2/library/stdtypes.html#str.replace ).

Tienes que usar el remódulo:

import re
newline= re.sub("<\/?\[[0-9]+>", "", line)
Zac
fuente
44
Debería usar en \d+lugar de[0-9]+
winklerrr
3

no tiene que usar expresiones regulares (para su cadena de muestra)

>>> 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
fuente
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
fuente