如果我有如下字符串:
foo_bar_one_two_three
有没有一种干净的方式,用正则表达式,返回:foo_bar_one_two
?
我知道我可以为此使用 split、pop 和 join,但我正在寻找更清洁的解决方案。
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]])
.
一种方法是使用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'
与rsplit
解决方案类似,rpartition
也将起作用:
result = my_string.rpartition("_")[0]
您需要注意找不到分隔符的情况。在这种情况下,原始字符串将在索引 2 中,而不是 0。
文档字符串:
rpartition(...)
S.rpartition(sep) -> (head, sep, tail)
在 S 中搜索分隔符 sep,从 S 的末尾开始,并返回它之前的部分、分隔符本身和它之后的部分。如果没有找到分隔符,则返回两个空字符串和 S。
这是一个通用函数,用于在最后一次出现任何指定字符串后删除所有内容。对于额外的功劳,它还支持在最后一次出现后删除所有内容。
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)
我知道是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"
希望 pythonsplit
函数的工作方式相同。:)
编辑:
使用函数的限制部分,您可以执行以下操作:
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]