Як ввести регулярний вираз у 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. . .


4
Прийнята відповідь вже охоплює вашу проблему і вирішує її. Вам потрібно ще щось?
HamZa

Яким повинен бути результат where the<[99> number ranges from 1-100</[100>?
utapyngo

він також повинен видалити число в <...>тегу, тому вихід повинен бутиwhere the number rangers from 1-100 ?
alvas

Відповіді:


565

Цей тестований фрагмент повинен це зробити:

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 . Час, який ви там проводите, окупить себе багато разів. Щасливого регенезингу!


так це працює !! дякую, але чи можете ви пояснити короткий вираз?
alvas

9
Також не нехтуйте Книгою про регулярні вирази - Освоєння регулярних виразів , Джефрі Фрідл
pcurry

Ще одна хороша довідка бачить w3schools.com/python/python_regex.asp
Карсон

38

str.replace()робить фіксовані заміни. Використовуйте re.sub()замість цього.


3
Також варто відзначити, що ваш візерунок повинен виглядати приблизно як "</ {0-1} \ d {1-2}>" або будь-який варіант, який використовує python нотації регулярного виразу.

3
Що означає фіксована заміна?
avi

@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 docs : {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

метод заміни рядкових об'єктів не приймає регулярні вирази, а лише фіксовані рядки (див. документацію: http://docs.python.org/2/library/stdtypes.html#str.replace ).

Ви повинні використовувати reмодуль:

import re
newline= re.sub("<\/?\[[0-9]+>", "", line)

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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.