วิธีการป้อน regex ใน string.replace?


317

ฉันต้องการความช่วยเหลือในการประกาศ regex อินพุตของฉันเป็นดังนี้:

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

ฉันได้ลองด้วย (แต่ดูเหมือนว่าฉันใช้ไวยากรณ์ regex ผิด):

    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)

Regexes สนุก! แต่ฉันขอแนะนำให้ใช้เวลาหนึ่งหรือสองชั่วโมงเพื่อศึกษาพื้นฐาน สำหรับ starters คุณต้องเรียนรู้ว่าอักขระใดเป็นพิเศษ: "metacharacters"ที่ต้องหลบหนี (เช่นมีเครื่องหมายแบ็กสแลชวางไว้ด้านหน้า - และกฎจะแตกต่างกันทั้งในและนอกคลาสอักขระ) มีบทช่วยสอนออนไลน์ที่ยอดเยี่ยมที่: www .regular-expressions.info เวลาที่คุณใช้อยู่ที่นั่นจะจ่ายให้ตัวเองหลายครั้ง มีความสุขในการลงทะเบียน!


ใช่มันใช้งานได้ !! ขอบคุณ แต่คุณสามารถอธิบายสั้น ๆ regex?
alvas

9
และอย่าละเลยหนังสือเกี่ยวกับนิพจน์ทั่วไป - Mastering Regular ExpressionsโดยJeffrey Friedl
pcurry

การอ้างอิงที่ดีอื่นเห็นw3schools.com/python/python_regex.asp
Carson

38

str.replace()จะแทนที่คงที่ ใช้re.sub()แทน


3
นอกจากนี้ควรสังเกตว่ารูปแบบของคุณควรมีลักษณะเช่น "</ {0-1} \ d {1-2}>" หรือตัวแปรใด ๆ ที่ใช้เครื่องหมายสัญกรณ์ regexp

3
การแทนที่แบบคงที่หมายถึงอะไร
avi

@avi บางทีเขาอาจหมายถึงการแทนที่คำที่คงที่ แต่ค่อนข้างบางคำที่ค้นหาผ่าน regex
Gunay Anach

สตริงคงที่ (ตัวอักษรคงที่)
vstepaniuk

23

ฉันจะไปเช่นนี้ (อธิบาย regex ในความคิดเห็น):

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)

หากคุณต้องการเรียนรู้เพิ่มเติมเกี่ยวกับ regex ฉันขอแนะนำให้อ่านCookbook นิพจน์ปกติโดย Jan Goyvaerts และ Steven Levithan


2
คุณสามารถใช้*แทน{0,}
HamZa

3
จากเอกสารหลาม : {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

วงเล็บเป็นสิ่งที่จำเป็นจริงๆเหรอ? นั่นจะเป็น regex เดียวกัน<[^>]+>หรือไม่: โดยวิธีการ: ฉันคิดว่า regex ของคุณจะจับคู่มากเกินไป (เช่นบางสิ่งบางอย่าง<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)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.