ksh风格的字符串左右去除匹配表达式?

5 投票
4 回答
903 浏览
提问于 2025-04-16 01:14

怎么才能把字符串左右两边的部分去掉,直到遇到一个匹配的表达式,就像在ksh中那样?

举个例子:

${name##*/}

${name%/*}

(可以查看http://www.well.ox.ac.uk/~johnb/comp/unix/ksh.html了解ksh的例子。)

我好像找不到一个简单的方法来使用re模块或string模块来做到这一点,但我一定是漏掉了什么。

4 个回答

2
${name##*/}

这相当于:

re.match(".*?([^/]*)$")[1]

${name%/*}

这相当于:

re.match("(.*?)[^/]*$")[1]
2

没有什么特别的方式来处理“从左边去掉”、“从右边去掉”等等。我们通常用一个通用的方法,就是 re.sub。比如说,如果你想“去掉最后一个斜杠之前的所有东西”(在 ksh 的概念中就是“从左边去掉”):

name = re.sub(r'(.*/)(.*)', r'\2', name)

而如果你想去掉“最后一个斜杠和它后面的所有东西”(在 ksh 中称为“从右边去掉”):

name = re.sub(r'(.*)/.*', r'\1', name)

这些匹配会尽可能多,因为正则表达式中的 * 是贪婪的;如果你想要非贪婪匹配(也就是“尽量少匹配”),可以用 *? 来代替。

3

Ksh:

$ s='abc/def/ghi'
$ echo ${s%%/*}
abc
$ echo ${s%/*}
abc/def
$ echo ${s#*/}
def/ghi
$ echo ${s##*/}
ghi

Python:

>>> s='abc/def/ghi'
>>> print s[:s.find("/")]
abc
>>> print s[:s.rfind("/")]
abc/def
>>> print s[s.find("/")+1:]
def/ghi
>>> print s[s.rfind("/")+1:]
ghi

编辑:

为了处理模式缺失的情况,正如ΤΖΩΤΖΙΟΥ所指出的:

>>> s='abc/def/ghi'
>>> t='no slash here'
>>> print s[:s.find("/") % (len(s) + 1)]
abc
>>> print t[:t.find("/") % (len(t) + 1)]
no slash here
>>> print s[:s.rfind("/") % (len(s) + 1)]
abc/def
>>> print t[:t.rfind("/") % (len(t) + 1)]
no slash here
>>> print s[s.find("/")+1:]
def/ghi
>>> print t[t.find("/")+1:]
no slash here
>>> print s[s.rfind("/")+1:]
ghi
>>> print t[t.rfind("/")+1:]
no slash here

撰写回答