Python使用正则表达式和replace()找到特定字符之间的子字符串
假设我有一个字符串,里面有很多乱七八糟的东西,比如下面这样:
strJunk ="asdf2adsf29Value=five&lakl23ljk43asdldl"
我想要获取在 'Value=' 和 '&' 之间的子字符串,在这个例子中就是 'five'。
我可以使用像下面这样的正则表达式:
match = re.search(r'Value=?([^&>]+)', strJunk)
>>> print match.group(0)
Value=five
>>> print match.group(1)
five
为什么 match.group(0) 是整个 'Value=five',而 group(1) 只是 'five'?有没有办法让我只得到 'five' 作为唯一的结果?(这个问题是因为我对正则表达式的理解还不太牢靠)
我还需要在这个字符串中进行替换,比如下面这样:
val1 = match.group(1)
strJunk.replace(val1, "six", 1)
这样会得到:
'asdf2adsf29Value=six&lakl23ljk43asdldl'
考虑到我打算反复执行上面这两项任务(找到 'Value=' 和 '&' 之间的字符串,以及替换这个值),我在想有没有其他更有效的方法来查找子字符串并在原字符串中替换它。我对现在的方法还可以,但我只是想确保如果有更好的方法,我不会浪费太多时间。
3 个回答
为什么 match.group(0) 会返回整个字符串 'Value=five',而 group(1) 只返回 'five' 呢?有没有办法让我只得到 'five' 作为结果?(这个问题是因为我对正则表达式的理解还不太牢靠)
我觉得使用“后向断言”可以帮到你。
>>> match = re.search(r'(?<=Value=)([^&>]+)', strJunk)
>>> match.group(0)
'five'
但是在后向断言中,你只能使用固定长度的字符串。
>>> match = re.search(r'(?<=Value=?)([^&>]+)', strJunk)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.6/re.py", line 142, in search
return _compile(pattern, flags).search(string)
File "/usr/lib/python2.6/re.py", line 245, in _compile
raise error, v # invalid expression
sre_constants.error: look-behind requires fixed-width pattern
我想不出不使用正则表达式的办法。你这样做的方式应该比后向断言更快。
我不太确定你是不是在解析网址,如果是的话,你肯定应该使用urlparse模块。
不过,既然这不是你的问题,使用正则表达式在多个字段上进行分割在Python中是非常快的,所以你应该可以按照下面的方式实现你想要的功能:
import re
strJunk ="asdf2adsf29Value=five&lakl23ljk43asdldl"
split_result = re.split(r'[&=]', strJunk)
split_result[1] = 'six'
print "{0}={1}&{2}".format(*split_result)
希望这对你有帮助!
编辑:
如果你需要多次分割,可以使用re.compile()来编译正则表达式。这样你就可以得到:
import re
rx_split_on_delimiters = re.compile(r'[&=]') # store this somewhere
strJunk ="asdf2adsf29Value=five&lakl23ljk43asdldl"
split_result = rx_split_on_delimiters.split(strJunk)
split_result[1] = 'six'
print "{0}={1}&{2}".format(*split_result)
命名组让你在之后更容易获取组里的内容。一次编译你的正则表达式,然后重复使用这个编译好的对象,比每次使用时都重新编译要高效得多(这就是你每次调用 re.search 时发生的事情)。你可以使用正向先行和后行断言,让这个正则表达式适合你想要进行的替换操作。
>>> value_regex = re.compile("(?<=Value=)(?P<value>.*?)(?=&)")
>>> match = value_regex.search(strJunk)
>>> match.group('value')
'five'
>>> value_regex.sub("six", strJunk)
'asdf2adsf29Value=six&lakl23ljk43asdldl'