如何找到k个连续数字后截断字符串?高效提取文件名4位数字前内容
让我来帮你解决这两个字符串处理的问题,直接上实用高效的方案:
问题1:找到k个连续数字后截断字符串
对于这个需求,正则表达式是最简洁高效的选择,它能精准定位第一个k位连续数字的位置,快速完成截断操作。
举个实际例子:假设k=4,我们要保留字符串中第一个4位数字出现前的内容,截断后面的部分:
import re def truncate_after_k_digits(s, k): # 匹配第一个k位连续数字的起始位置 match = re.search(r'\d{' + str(k) + '}', s) if match: return s[:match.start()] # 没找到k位数字时返回原字符串 return s # 测试用例 test_str = "project_v2_202406_data_56789" print(truncate_after_k_digits(test_str, 4)) # 输出: project_v2_2024
如果你的需求是截断到k位数字的末尾(比如上面例子要得到project_v2_202406_data_5678),只需要把返回值改成s[:match.end()]即可。
问题2:提取*.1243.*格式文件名中4位数字前的内容
你的原代码确实有点繁琐,既要分割字符串又要循环判断数字范围,效率和可读性都有优化空间。这里推荐两种更优的方案:
方案1:正则表达式(最推荐)
直接用正则匹配文件名的结构,一次性提取目标内容,代码简洁且高效:
import re file_list = ["invoice.1234.pdf", "receipt_2023.5678.txt", "document.987.docx"] # 匹配任意字符(非贪婪模式),直到遇到".4位数字."的结构 pattern = re.compile(r'(.*?)\.\d{4}\.') names = [pattern.match(file).group(1) for file in file_list if pattern.match(file)] print(names) # 输出: ['invoice', 'receipt_2023']
为什么这个方案更好?
- 无需循环分割后的每个元素,一次正则匹配就能定位目标内容
- 用
\d{4}精准匹配4位数字,省去了转整数判断范围的开销 - 列表推导式替代多层循环,代码更简洁,执行效率更高
方案2:优化版字符串分割(如果不想用正则)
如果对正则不太熟悉,也可以优化原有的分割逻辑,减少不必要的操作:
file_list = ["invoice.1234.pdf", "receipt_2023.5678.txt", "document.987.docx"] names = [] for file in file_list: parts = file.split('.') for idx, part in enumerate(parts): # 直接判断长度为4且是数字,比转整数判断范围更快 if len(part) == 4 and part.isdigit(): names.append('.'.join(parts[:idx])) break print(names) # 输出: ['invoice', 'receipt_2023']
这个优化点在于用len(part) ==4替代了int(word)>999 and int(word)<10000,避免了字符串转整数的额外开销,效率比原代码提升不少。
内容的提问来源于stack exchange,提问作者Mitchell Faas
相关产品推荐
相关产品推荐

