How to input a regex in string.replace?

2019-01-01 12:04发布

问题:

I need some help on declaring a regex. My inputs are like the following:

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>

The required output is:

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

I\'ve tried this:

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

I\'ve also tried this (but it seems like I\'m using the wrong regex syntax):

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

I dont want to hard-code the replace from 1 to 99 . . .

回答1:

This tested snippet should do it:

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

Edit: Here\'s a commented version explaining how it works:

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 are fun! But I would strongly recommend spending an hour or two studying the basics. For starters, you need to learn which characters are special: \"metacharacters\" which need to be escaped (i.e. with a backslash placed in front - and the rules are different inside and outside character classes.) There is an excellent online tutorial at: www.regular-expressions.info. The time you spend there will pay for itself many times over. Happy regexing!



回答2:

str.replace() does fixed replacements. Use re.sub() instead.



回答3:

I would go like this (regex explained in comments):

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)

If you want to learn more about regex I recomend to read Regular Expressions Cookbook by Jan Goyvaerts and Steven Levithan.



回答4:

The easiest way

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


回答5:

replace method of string objects does not accept regular expressions but only fixed strings (see documentation: http://docs.python.org/2/library/stdtypes.html#str.replace).

You have to use re module:

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


回答6:

don\'t have to use regular expression (for your sample string)

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