Jak wprowadzić wyrażenie regularne w string.replace?

317

Potrzebuję pomocy w zadeklarowaniu wyrażenia regularnego. Moje dane wejściowe są następujące:

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>

Wymagana moc wyjściowa to:

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

Próbowałem tego:

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

Próbowałem również tego (ale wygląda na to, że używam złej składni wyrażenia regularnego):

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

Nie chcę kodować replaceod 1 do 99. . .

alvas
źródło
4
Przyjęta odpowiedź już obejmuje Twój problem i rozwiązuje go. Potrzebujesz czegoś jeszcze ?
HamZa
Po co powinien być wynik where the<[99> number ranges from 1-100</[100>?
utapyngo
powinien także usunąć liczbę ze <...>znacznika, więc wynik powinien wynosićwhere the number rangers from 1-100 ?
alvas

Odpowiedzi:

565

Ten przetestowany fragment powinien to zrobić:

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

Edycja: Oto skomentowana wersja wyjaśniająca, jak to działa:

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)

Regeksy są fajne! Ale zdecydowanie zaleciłbym spędzenie godziny lub dwóch na studiowaniu podstaw. Na początek musisz dowiedzieć się, które postacie są wyjątkowe: „metaznaki”, które należy uciec (tj. Z ukośnikiem umieszczonym z przodu - a zasady są różne wewnątrz i na zewnątrz klas postaci). Doskonały samouczek online na: www .regular-expressions.info . Czas tam spędzony zwróci się wiele razy. Szczęśliwego wyrażenia regularnego!

ridgerunner
źródło
tak to działa !! dzięki, ale czy potrafisz krótko wyjaśnić wyrażenie regularne?
alvas
9
Nie zaniedbuj również książki o wyrażeniach regularnych - opanowanie wyrażeń regularnych , autor: Jeffrey Friedl
pcurry
Kolejne dobre referencje to w3schools.com/python/python_regex.asp
Carson
38

str.replace()naprawia zamienniki. Użyj re.sub()zamiast tego.

Ignacio Vazquez-Abrams
źródło
3
Warto również zauważyć, że wzorzec powinien wyglądać jak „</ {0-1} \ d {1-2}>” lub jakikolwiek inny wariant pythonowej notacji regularnej.
3
Co oznaczają stałe wymiany?
avi
@avi Prawdopodobnie miał na myśli naprawione zastępowanie słów raczej częściowe lokalizowanie słów przez wyrażenie regularne.
Gunay Anach,
naprawione (dosłowne, stałe) ciągi znaków
vstepaniuk
23

Chciałbym pójść tak (regex wyjaśnione w komentarzach):

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)

Jeśli chcesz dowiedzieć się więcej o wyrażeniach regularnych, polecam przeczytać książkę kucharską wyrażeń regularnych autorstwa Jana Goyvaertsa i Stevena Levithana.

Lorenzo Persichetti
źródło
2
Możesz po prostu użyć *zamiast{0,}
HamZa
3
Z dokumentacji dochon : {0,}jest taki sam jak *, {1,}jest równoważny +i {0,1}taki sam jak ?. Lepiej jest używać *, +lub ?kiedy możesz, po prostu dlatego, że są krótsze i łatwiejsze do odczytania.
winklerrr,
15

Najłatwiejszy sposób

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
źródło
Czy nawiasy są naprawdę potrzebne? Czy to nie byłoby to samo regex: <[^>]+>? Nawiasem mówiąc: myślę, że twoje wyrażenie regularne byłoby zbyt duże (np. Coś takiego <html>)
winklerrr
3

nie musisz używać wyrażenia regularnego (dla przykładowego ciągu znaków)

>>> 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
źródło
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
źródło