我想提取下面9位数字之前的字符串:
tmp = place1_128017000_gw_cl_mask.tif
输出应为place1
我可以这样做:tmp.split('_')[0]
,但我也希望解决方案的工作:
tmp = place1_place2_128017000_gw_cl_mask.tif
,其结果为:place1_place2
你可以假设这个数字也是9位长
使用正则表达式和regex的forward特性,这是一个简单的解决方案:
tmp = "place1_place2_128017000_gw_cl_mask.tif"
m = re.search(r'.+(?=_d{9}_)', tmp)
print(m.group())
结果:
place1_place2
注意d{9}
位正好匹配9位数字。(?= ... )
中的regex位是一个前瞻性的,这意味着它不是实际匹配的一部分,但只有在匹配之后才匹配。
假设我们可以将您的问题描述为希望子字符串达到但不包括后跟所有数字的下划线,我们可以尝试:
tmp = "place1_place2_128017000_gw_cl_mask.tif"
m = re.search(r'^([^_]+(?:_[^_]+)*)_d+_', tmp)
print(m.group(1)) # place1_place2
使用正则表达式:
import re
places = (
"place1_128017000_gw_cl_mask.tif",
"place1_place2_128017000_gw_cl_mask.tif",
)
pattern = re.compile("(placed+(?:_placed+)*)_d{9}")
for p in places:
matched = pattern.match(p)
if matched:
print(matched.group(1))
打印:文化
流行
place1_place2
正则表达式的工作方式是这样的(根据需要调整,例如,小于9位或可变位数):
(
开始捕获placed+
匹配"位置+ 1到多位数";(?:
开始一个群体,但不捕捉它(不需要捕获)_placed+
匹配更多"位置">)
关闭组*
表示零或多倍于前一组)
关闭捕获d{9}
匹配9位
结果在第一个(也是唯一一个)捕获组中。
这里有一个不使用regex(未优化!)的可能解决方案:
def extract(s):
result = ''
for x in s.split('_'):
try: x = int(x)
except: pass
if isinstance(x, int) and len(str(x)) == 9:
return result[:-1]
else:
result += x + '_'
tmp = 'place1_128017000_gw_cl_mask.tif'
tmp2 = 'place1_place2_128017000_gw_cl_mask.tif'
print(extract(tmp)) # place1
print(extract(tmp2)) # place1_place2