我有一个文件名列表,它们都是这样的:
orl_faces/s22/3.pgm
我正在尝试提取字母 s 前面的数字,如下所示:
re.findall(r'[s][0-9]*','orl_faces/s22/3.pgm')
但它不起作用,有什么建议吗?
使用零宽度的正后视:
(?<=s)d+
-
d+
匹配一个或多个数字,(?<=s)
确保s
在数字之前
边缘情况:
例如,在字符串orl_faces3/s22/3.pgm
的情况下,它将匹配3
。因此,我们需要使用更严格的模式,根据您的示例,我们可以选择匹配/s3
作为前面的令牌:
(?<=/s)d+
这可能是其他东西,比如数字后面需要跟/
,对/
有一个积极的展望:
(?<=/s)d+(?=/)
不过,您需要找出确切的用例。
另一种选择是使用re.findall
,将所有匹配项放在一个列表中并做出选择——但这非常脆弱且适得其反,最好使用限制性的常规模式。
例:
In [64]: s = 'orl_faces/s22/3.pgm'
In [65]: re.search(r'(?<=s)d+', s).group()
Out[65]: '22'
In [66]: s = 'orl_faces3/s22/3.pgm'
In [67]: re.search(r'(?<=s)d+', s).group()
Out[67]: '3'
In [68]: re.search(r'(?<=/s)d+(?=/)', s).group()
Out[68]: '22'
您可以使用组运算符:
match = re.search(r'/s(d+)/', my_string)
print(match.group(1))
这对我有用:
re.search(r'/s([0-9]+)/','orl_faces/s22/3.pgm')[1]
'22'
您的表达式使用 [s]
.这从字面上匹配[s]
(它不仅仅是匹配s
因为你在[
之前放了一个反斜杠,因此它是从字面上解释的(。
法典
在此处查看其使用情况
(?<=s)d+(?=/)
确保/
先于您可以使用s
(?<=/s)d+(?=/)
用法
在此处查看正在使用的代码
import re
r = r"(?<=s)d+(?=/)"
s = "orl_faces/s22/3.pgm"
print(re.findall(r, s))
<小时 />解释
-
(?<=s)
积极的回溯,确保前面的内容与字面s
匹配 -
d+
匹配一个或多个数字 -
(?=/)
积极的展望,确保接下来的内容/
字面上匹配- OP 指定的数字,前面有
s
,后面是/
- OP 指定的数字,前面有
>>> re.findall(r's(d+)/', 'orl_faces/s22/3.pgm')
['22']