You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中用正则表达式提取字符串中的ID和DIRECTION字段?

基于命名规则用正则表达式提取ID和DIRECTION字段

需求说明

  • 从查询字符串中提取ID和DIRECTION两个字段:
    • DIRECTION的值仅能是1或2;
    • ID可以是文件系统允许的任意字符串(如字母数字、-、_、.)。
  • 计划实现的函数框架如下:
def extract_fields(query: str, naming_scheme: str):
    # 实现代码
    return (ID, DIRECTION)

测试示例

命名规则1

naming_scheme_1 = "[ID]_R[DIRECTION].fastq.gz"
# 测试用例1
ID, DIRECTION = extract_fields("Kuwait_110_S59_R1.fastq.gz", naming_scheme_1)
# 预期结果:ID = "Kuwait_110_S59",DIRECTION = "1"
# 测试用例2
ID, DIRECTION = extract_fields("Kuwait_110_S59_R2.fastq.gz", naming_scheme_1)
# 预期结果:ID = "Kuwait_110_S59",DIRECTION = "2"

命名规则2

naming_scheme_2 = "[ID]_R[DIRECTION]_001.fastq.gz"
# 测试用例1
ID, DIRECTION = extract_fields("Kuwait_110_S59_R1_001.fastq.gz", naming_scheme_2)
# 预期结果:ID = "Kuwait_110_S59",DIRECTION = "1"
# 测试用例2
ID, DIRECTION = extract_fields("Kuwait_110_S59_R2_001.fastq.gz", naming_scheme_2)
# 预期结果:ID = "Kuwait_110_S59",DIRECTION = "2"

命名规则3

naming_scheme_3 = "barcode-[ID]_[DIRECTION].fq"
# 测试用例1
ID, DIRECTION = extract_fields("barcode-Kuwait_110_S59_1.fq", naming_scheme_3)
# 预期结果:ID = "Kuwait_110_S59",DIRECTION = "1"
# 测试用例2
ID, DIRECTION = extract_fields("barcode-Kuwait_110_S59_2.fq", naming_scheme_3)
# 预期结果:ID = "Kuwait_110_S59",DIRECTION = "2"

当前问题

之前尝试用多次字符串拆分的方式实现,但效果不佳,希望用正则表达式完成该需求。


解决方案

核心思路是把自定义的命名规则转换成正则表达式,将[ID]和[DIRECTION]替换为对应的捕获组,同时转义命名规则中的正则特殊字符(如.)。

实现代码如下:

import re

def extract_fields(query: str, naming_scheme: str):
    # 用临时占位符替换[ID]和[DIRECTION],避免转义正则特殊字符时被误处理
    temp_scheme = naming_scheme.replace("[ID]", "__ID_PLACEHOLDER__")
    temp_scheme = temp_scheme.replace("[DIRECTION]", "__DIR_PLACEHOLDER__")
    # 转义命名规则中的正则特殊字符
    escaped_scheme = re.escape(temp_scheme)
    # 替换回对应的正则捕获组
    regex_pattern = escaped_scheme.replace("__ID_PLACEHOLDER__", "(?P<ID>[\\w\\-.]+)")
    regex_pattern = regex_pattern.replace("__DIR_PLACEHOLDER__", "(?P<DIRECTION>[12])")
    # 加上首尾锚点,确保查询字符串完全匹配命名规则
    regex_pattern = f"^{regex_pattern}$"
    
    match = re.match(regex_pattern, query)
    if not match:
        raise ValueError(f"查询字符串 {query} 不符合命名规则 {naming_scheme}")
    
    return (match.group("ID"), match.group("DIRECTION"))

验证测试

运行以下代码验证效果:

# 测试命名规则1
naming_scheme_1 = "[ID]_R[DIRECTION].fastq.gz"
print(extract_fields("Kuwait_110_S59_R1.fastq.gz", naming_scheme_1))  # 输出: ('Kuwait_110_S59', '1')
print(extract_fields("Kuwait_110_S59_R2.fastq.gz", naming_scheme_1))  # 输出: ('Kuwait_110_S59', '2')

# 测试命名规则2
naming_scheme_2 = "[ID]_R[DIRECTION]_001.fastq.gz"
print(extract_fields("Kuwait_110_S59_R1_001.fastq.gz", naming_scheme_2))  # 输出: ('Kuwait_110_S59', '1')
print(extract_fields("Kuwait_110_S59_R2_001.fastq.gz", naming_scheme_2))  # 输出: ('Kuwait_110_S59', '2')

# 测试命名规则3
naming_scheme_3 = "barcode-[ID]_[DIRECTION].fq"
print(extract_fields("barcode-Kuwait_110_S59_1.fq", naming_scheme_3))  # 输出: ('Kuwait_110_S59', '1')
print(extract_fields("barcode-Kuwait_110_S59_2.fq", naming_scheme_3))  # 输出: ('Kuwait_110_S59', '2')

代码说明

  1. 临时占位符替换:先把[ID]和[DIRECTION]换成临时字符串,避免在转义正则特殊字符时被误处理;
  2. 正则转义:用re.escape()转义命名规则中的特殊字符(比如.会被转义成\.,确保匹配实际的点号);
  3. 捕获组定义:
    • (?P<ID>[\\w\\-.]+):匹配ID允许的所有字符(字母数字、下划线、连字符、点号);
    • (?P<DIRECTION>[12]):仅匹配1或2;
  4. 完全匹配校验:给正则表达式加上^和$,确保查询字符串完全符合命名规则,避免部分匹配导致的错误。

内容的提问来源于stack exchange,提问作者O.rka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 21:15:06