12

如果我有如下字符串:

foo_bar_one_two_three

有没有一种干净的方式,用正则表达式,返回:foo_bar_one_two

我知道我可以为此使用 split、pop 和 join,但我正在寻找更清洁的解决方案。

4

5 回答 5

24
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]]).

于 2013-09-11T00:54:37.337 回答
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'
于 2013-09-11T00:56:58.473 回答
2

rsplit解决方案类似,rpartition也将起作用:

result = my_string.rpartition("_")[0]

您需要注意找不到分隔符的情况。在这种情况下,原始字符串将在索引 2 中,而不是 0。

文档字符串:

rpartition(...)

S.rpartition(sep) -> (head, sep, tail)

在 S 中搜索分隔符 sep,从 S 的末尾开始,并返回它之前的部分、分隔符本身和它之后的部分。如果没有找到分隔符,则返回两个空字符串和 S。

于 2013-09-11T01:09:42.707 回答
1

这是一个通用函数,用于在最后一次出现任何指定字符串后删除所有内容。对于额外的功劳,它还支持在最后一次出现后删除所有内容。

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)
于 2020-12-26T06:09:35.557 回答
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"

希望 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]
于 2013-09-11T00:57:03.023 回答