Come inserire un regex in string.replace?


317

Ho bisogno di aiuto per dichiarare una regex. I miei input sono i seguenti:

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>

L'output richiesto è:

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

Ho provato questo:

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

Ho anche provato questo (ma sembra che sto usando la sintassi regex sbagliata):

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

Non voglio codificare replaceda 1 a 99. . .


4
La risposta accettata copre già il tuo problema e lo risolve. Avete bisogno di altro ?
HamZa,

Quale dovrebbe essere il risultato per where the<[99> number ranges from 1-100</[100>?
utapyngo,

dovrebbe anche rimuovere il numero nel <...>tag, quindi l'output dovrebbe esserewhere the number rangers from 1-100 ?
alvas il

Risposte:


566

Questo frammento testato dovrebbe farlo:

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

Modifica: ecco una versione commentata che spiega come funziona:

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)

I regex sono divertenti! Consiglio vivamente di passare un'ora o due a studiare le basi. Per i principianti, devi imparare quali personaggi sono speciali: "metacaratteri" che devono essere sfuggiti (cioè con una barra rovesciata posta davanti - e le regole sono diverse all'interno e all'esterno delle classi di caratteri.) Esiste un eccellente tutorial online su: www .regular-expressions.info . Il tempo che trascorrerai li ripagherà da solo molte volte. Felice regexing!


sì funziona !! grazie ma puoi spiegare la regex in breve?
alvas,

9
Inoltre, non trascurare The Book on Regular Expressions - Mastering Regular Expressions , di Jeffrey Friedl
pcurry

Un altro buon riferimento vede w3schools.com/python/python_regex.asp
Carson

38

str.replace()fa riparazioni fisse. Usa re.sub()invece.


3
Vale anche la pena notare che il tuo modello dovrebbe assomigliare a "</ {0-1} \ d {1-2}>" o qualsiasi altra variante della notazione regexp usata da Python.

3
Cosa significa sostituzioni fisse?
avi

@avi Probabilmente intendeva la sostituzione di parole fisse piuttosto che la localizzazione parziale di parole attraverso regex.
Gunay Anach l'

stringhe fisse (letterali, costanti)
vstepaniuk

23

Vorrei andare così (regex spiegato nei commenti):

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)

Se vuoi saperne di più su regex, ti consiglio di leggere il ricettario sulle espressioni regolari di Jan Goyvaerts e Steven Levithan.


2
Potresti semplicemente usare *invece di{0,}
HamZa il

3
Dai documenti di Python : {0,}è uguale a *, {1,}è equivalente a +ed {0,1}è uguale a ?. È meglio usarlo *, +o ?quando è possibile, semplicemente perché sono più brevi e più facili da leggere.
winklerrr,

15

La via più facile

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

Le parentesi sono davvero necessarie? Non sarebbe la stessa espressione regolare: <[^>]+>? A proposito: penso che il tuo regex corrisponderebbe troppo (ad esempio qualcosa del genere <html>)
winklerrr


3

non è necessario utilizzare l'espressione regolare (per la stringa di esempio)

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

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)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.