Как ввести регулярное выражение в string.replace?

317

Мне нужна помощь в объявлении регулярного выражения. Мои данные похожи на следующие:

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>

Требуемый результат:

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

Я пробовал это:

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

Я также попробовал это (но похоже, что я использую неправильный синтаксис регулярных выражений):

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

Я не хочу жестко кодировать replaceот 1 до 99. , ,

Alvas
источник
4
Принятый ответ уже охватывает вашу проблему и решает ее. Тебе нужно что-то еще ?
HamZa
Для чего должен быть результат where the<[99> number ranges from 1-100</[100>?
utapyngo
он также должен удалить номер в <...>теге, поэтому вывод должен бытьwhere the number rangers from 1-100 ?
alvas

Ответы:

566

Этот проверенный фрагмент должен сделать это:

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

Изменить: Вот прокомментированная версия, объясняющая, как это работает:

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)

Регексы это весело! Но я бы настоятельно рекомендовал потратить час или два на изучение основ. Для начала вам нужно узнать, какие символы являются особыми: «метасимволы», которые необходимо экранировать (т. Е. С обратной косой чертой, расположенной спереди - и правила различаются внутри и снаружи классов персонажей.) Отличное онлайн-руководство можно найти по адресу: www .regular-expressions.info . Время, проведенное там, окупится много раз. Счастливое регулярное выражение!

ridgerunner
источник
да, это работает !! спасибо, но не могли бы вы вкратце объяснить регулярное выражение?
alvas
9
Также не пренебрегайте книгой о регулярных выражениях - освоение регулярных выражений , Джеффри Фридлом
pcurry
Еще одна хорошая ссылка
Карсон
38

str.replace()делает фиксированные замены. Используйте re.sub()вместо этого.

Игнасио Васкес-Абрамс
источник
3
Также стоит отметить, что ваш шаблон должен выглядеть примерно как "</ {0-1} \ d {1-2}>" или любой другой вариант регулярного выражения нотации, который использует python.
3
Что означают фиксированные замены?
Ави
@avi Вероятно, он имел в виду замену фиксированного слова, а не частичное нахождение слова через регулярное выражение.
Гунай Анач
исправлены (буквальные, постоянные) строки
vstepaniuk
23

Я бы пошел так (регулярное выражение объясняется в комментариях):

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)

Если вы хотите больше узнать о регулярных выражениях, я рекомендую прочитать « Поваренную книгу регулярных выражений» Яна Гойваэрта и Стивена Левитана.

Лоренцо Персикетти
источник
2
Вы можете просто использовать *вместо{0,}
HamZa
3
Из документации на Python : {0,}то же самое *, {1,}эквивалентно +, и {0,1}то же самое, что и ?. Лучше использовать *, +или ?когда вы можете, просто потому, что они короче и легче для чтения.
winklerrr
15

Самый простой способ

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
Иезекииль Маркес
источник
Действительно ли скобки нужны? Разве это не то же самое регулярное выражение <[^>]+>? Кстати: я думаю, что ваше регулярное выражение будет слишком много (например, что-то вроде <html>)
winklerrr
10

Метод replace для строковых объектов не принимает регулярные выражения, а только фиксированные строки (см. документацию: http://docs.python.org/2/library/stdtypes.html#str.replace ).

Вы должны использовать reмодуль:

import re
newline= re.sub("<\/?\[[0-9]+>", "", line)
Zac
источник
4
Вы должны использовать \d+вместо[0-9]+
Winklerrr
3

не нужно использовать регулярное выражение (для вашего образца строки)

>>> 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)
Абена Саулка
источник