使用正则表达式从字符串中删除最后一个字符 _ 的 Python 方法

3
我知道有很多其他的正则表达式问题,但我希望有人能指出我的正则表达式有什么问题。我已经做了一些研究,看起来它应该可以工作。我用rubular测试过它,是的,我知道那是ruby的正则表达式,但我使用的规则应该适用于python,就像在python文档中所描述的那样。
目前我有
a = ["SDFSD_SFSDF234234","SDFSDF_SDFSDF_234324","TSFSD_SDF_213123"]
c = [re.sub(r'[A-Z]+', "", x) for x in a]

这个函数返回

['SDFSD_SFSDF', 'SDFSDF_SDFSDF_', 'TSFSD_SDF_']

但我希望它能返回
['SDFSD_SFSDF', 'SDFSDF_SDFSDF', 'TSFSD_SDF']

我尝试使用这个正则表达式

c = [re.sub(r'$?_[^A-Z_]+', "", x) for x in a]

但是我遇到了这个错误。
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.6/re.py", line 151, in sub
    return _compile(pattern, 0).sub(repl, string, count)
  File "/usr/lib64/python2.6/re.py", line 245, in _compile
    raise error, v # invalid expression

有人能帮我找出我做错了什么吗?


3
你的代码返回结果不正确:c 应该是 ['_234234', '__234324', '__213123'] - arshajii
5个回答

2
import re

a = ["SDFSD_SFSDF234234","SDFSDF_SDFSDF_234324","TSFSD_SDF_213123"]
c = [re.match(r'[A-Z_]+[A-Z]', x).group() for x in a]

print c

结果:

['SDFSD_SFSDF', 'SDFSDF_SDFSDF', 'TSFSD_SDF']

请注意,在您的示例中使用的“re.sub”是一个正则表达式替换命令,而不是搜索。您的正则表达式似乎匹配您要求的内容,而不是您想要摆脱以获取所需内容。

2
>>> import re
>>> a = ["SDFSD_SFSDF234234","SDFSDF_SDFSDF_234324","TSFSD_SDF_213123"]
>>> c = [re.sub('_?\d+','',x) for x in a]
>>> c
['SDFSD_SFSDF', 'SDFSDF_SDFSDF', 'TSFSD_SDF']
>>>

这段话很简短明了。基本上它的意思是“替换所有由数字组成的流或者由 _ 前缀的数字流”。


2

不使用正则表达式,使用 rstrip

a = ["ends_with_underscore_", "does_not", "multiple_____"]
b = [ x.rstrip("_") for x in a]
print b

>> ['ends_with_underscore', 'does_not', 'multiple']

1

错误在:

c = [re.sub(r'$?_[^A-Z_]+', "", x) for x in a]

由于?前面没有任何字符,因此它不知道要匹配0次还是1次。如果您将其更改为:
>>> [re.sub(r'_?[^A-Z_]+$', "", x) for x in a]
['SDFSD_SFSDF', 'SDFSDF_SDFSDF', 'TSFSD_SDF']

它按照你的期望工作。

另外,$ 用于表示行尾,因此它可能不应该是第一个字符。


1
你可以在正则表达式中插入“向前查看”。用(?=...)表示,你的正则表达式只会匹配紧随着...后面的文本。所以在你的情况下,你可以选择忽略下划线,除非它后面跟着[A-Z]。你的正则表达式将如下所示:r'[A-Z]+_(?[A-Z])',因此不跟在字母后面的下划线将被忽略。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接