正则表达式python -在列表中查找第二个字符“_”到字符“”之间具有相同数字的匹配项,

xzv2uavs  于 2022-12-10  发布在  Python
关注(0)|答案(5)|浏览(150)

我有以下列表:

list_paths=imgs/foldeer/img_ABC_21389_1.tif.tif,
imgs/foldeer/img_ABC_15431_10.tif.tif,
imgs/foldeer/img_GHC_561321_2.tif.tif,
imgs_foldeer/img_BCL_871125_21.tif.tif,
...

我希望能够运行一个for循环来匹配具有特定数字的字符串,该数字是第二次出现的“_”与“. tif.tif”之间的数字,例如,当数字为1时,要匹配的字符串是“imgs/foldeer/img_ABC_21389_1.tif.tif”,对于数字2,匹配字符串将是“imgs/foldeer/img_GHC_561321_2.tif.tif”。
我已经在Regex101上测试了这个正则表达式:

[^\r\n_]+\.[^\r\n_]+\_([0-9])

但这并不匹配任何内容,也不能确保它将采用确切的数字,因此如果数字为1,它也可能选择数字为10的项目。

我的最终目标是能够使用正则表达式匹配列表中请求编号介于第二次出现的“_”和第一次出现的“.tif”之间的项目,并查找正则表达式的帮助。

EDIT:输出应该是整个路径,而不仅仅是数字。

u4dcyp6a

u4dcyp6a1#

[0-9]*(?=\.tif\.tif)

这个正则表达式使用lookahead来捕获最后一组数字(您要查找的数字)

aamkag61

aamkag612#

我将向您展示一个我讨厌的、可以正常工作但同样丑陋的正则表达式:

data = ["imgs/foldeer/img_ABC_21389_1.tif.tif",
"imgs/foldeer/img_ABC_21389_1.tif.tif",
"imgs/foldeer/img_ABC_15431_10.tif.tif",
"imgs/foldeer/img_GHC_561321_2.tif.tif",
"imgs_foldeer/img_BCL_871125_21.tif.tif"]

numbers = [int(x.split("_",3)[-1].split(".")[0]) for x in data]
  • 第一次分割会产生“. tif.tif”
  • 提取最后一个元素
  • 这次再用点分割,取第一个元素(即字符串形式的数字),将其转换为int

请记住,它只适用于您提供的格式,在此解决方案中没有任何灵活性(另一方面,regex也没有给予任何灵活性)

qybjjes1

qybjjes13#

如果允许,则不使用正则表达式。

import re
s= 'imgs/foldeer/img_ABC_15431_10.tif.tif'
last =s[s.rindex('_')+1:]
print(re.findall(r'\d+', last)[0])

给出编号

10
rjee0c15

rjee0c154#

试试这个:

import re

s = '''imgs/foldeer/img_ABC_21389_1.tif.tif
imgs/foldeer/img_ABC_15431_10.tif.tif
imgs/foldeer/img_GHC_561321_2.tif.tif
imgs_foldeer/img_BCL_871125_21.tif.tif'''


number = 1
res1 = re.findall(f".*_{number}\.tif.*", s)

number = 21
res21 = re.findall(f".*_{number}\.tif.*", s)

print(res1)
print(res21)

结果

['imgs/foldeer/img_ABC_21389_1.tif.tif']
['imgs_foldeer/img_BCL_871125_21.tif.tif']
hpxqektj

hpxqektj5#

您的模式[^\r\n_]+\.[^\r\n_]+\_([0-9])不匹配任何内容,因为您在匹配一个点号之后匹配了一个下划线\_(请注意,您不必对它进行转义),而在示例数据中没有出现这种情况。
然后您想要匹配一个数字,但可用的数字只出现在任何点之前。
在您的问题中,您所指的数字在第三次出现_之后
要获得路径,可以将数字设置为要查找的数字的变量:

^\S*?/(?:[^\s_/]+_){3}\d+\.tif\b[^\s/]*$

说明

  • \S*?尽可能少地匹配可选的非空白字符
  • /逐字匹配
  • (?:[^\s_/]+_){3}匹配3次(非连续)_
  • \d+匹配1位以上的数字
  • \.tif\b[^\s/]*匹配后跟除/之外的任何字符的.tif
  • $字符串结束

请参阅regex demoPython demo
使用re.findall返回给定编号的所有路径的示例:

import re

number = 10
pattern = rf"^\S*?/(?:[^\s_/]+_){{3}}{number}\.tif\b[^\s/]*$"

s = ("imgs/foldeer/img_ABC_21389_1.tif.tif\n"
            "imgs/foldeer/img_ABC_15431_10.tif.tif\n"
            "imgs/foldeer/img_GHC_561321_2.tif.tif\n"
            "imgs_foldeer/img_BCL_871125_21.tif.tif\n"
            "imgs_foldeer/img_BCL_871125_21.png.tif"
     )

print(re.findall(pattern, s, re.M))

输出量

['imgs/foldeer/img_ABC_15431_10.tif.tif']

相关问题