如果我有一个字符串如下:
foo_bar_one_two_three
是否有一种干净的方式,使用RegEx,返回:foo_bar_one_two
?
我知道我可以使用split,pop和join,但我正在寻找更清洁的解决方案。
答案 0 :(得分:13)
result = my_string.rsplit('_', 1)[0]
其行为如下:
>>> my_string = 'foo_bar_one_two_three'
>>> print(my_string.rsplit('_', 1)[0])
foo_bar_one_two
请参阅str.rsplit([sep[, maxsplit]])
的文档条目。
答案 1 :(得分:2)
一种方法是使用rfind
获取最后_
个字符的索引,然后对字符串进行切片以提取字符到该点:
>>> s = "foo_bar_one_two_three"
>>> idx = s.rfind("_")
>>> if idx >= 0:
... s = s[:idx]
...
>>> print s
foo_bar_one_two
您需要检查rfind
调用返回大于-1的值,然后再使用它来获取子字符串,否则它将删除最后一个字符。
如果你必须使用正则表达式(我倾向于选择非正则表达式解决方案来处理这样的简单情况),你可以这样做:
>>> import re
>>> s = "foo_bar_one_two_three"
>>> re.sub('_[^_]*$','',s)
'foo_bar_one_two'
答案 2 :(得分:1)
类似于rsplit
解决方案,rpartition
也可以使用:
result = my_string.rpartition("_")[0]
您需要注意找不到分隔符的情况。在这种情况下,原始字符串将在索引2中,而不是0。
doc string:
rpartition(...)
S.rpartition(sep) - > (头,sep,尾巴)
在S中搜索S中的分隔符sep,然后返回 它之前的部分,分隔符本身以及它之后的部分。如果 找不到分隔符,返回两个空字符串和S.
答案 3 :(得分:1)
这是一个通用函数,用于删除任何指定字符串最后一次出现后的所有内容。额外的功劳,它还支持在第 n 个最后一次出现之后删除所有内容。
def removeEverythingAfterLast (needle, haystack, n=1):
while n > 0:
idx = haystack.rfind(needle)
if idx >= 0:
haystack = haystack[:idx]
n -= 1
else:
break
return haystack
在您的情况下,要删除最后一个“_”之后的所有内容,您只需像这样调用它:
updatedString = removeEverythingAfterLast('_', yourString)
如果您想删除倒数第二个“_”之后的所有内容,您可以这样调用:
updatedString = removeEverythingAfterLast('_', yourString, 2)
答案 4 :(得分:0)
我知道是python,我的答案可能在语法上有点不对,但在java中你会这样做:
String a = "foo_bar_one_two_three";
String[] b = a.split("_");
String c = "";
for(int i=0; i<b.length-1; a++){
c += b[i];
if(i != b.length-2){
c += "_";
}
}
//and at this point, c is "foo_bar_one_two"
希望python split
函数的工作方式相同。 :)
编辑:
使用功能的限制部分,您可以:
String a = "foo_bar_one_two_three";
String[] b = a.split("_",StringUtils.countMatches(a,"_"));
//and at this point, b is the array = [foo,bar,one,two]