使用正则表达式进行类型验证

Using regex for type validation

我说要学习正则表达式,我正在尝试使用它来解决问题。 我需要编写一个获取 VCF 文件的函数,并且需要检查文件中的某些列,看看它们是否符合要求。

第一列应以“chr”开头,以 1-99 之间的任意数字或字母“M,X,Y”中的一个结尾。 第二列必须是大于 0 的所有 int 数字。 第 4 和第 5 列需要是下一个字母“ATCG”之一(只有一个)。 如果其中一个陈述即使在一行中也是错误的,它应该 return false.

这是我写的代码:

def isVCF(file):
    with open(file, "r+") as my_file:
        lines = my_file.readlines()
        for line in lines:
            columns = line.split("\t")
        num_format = re.compile("^[+]?[1-9][0-9]*\.?[0-9]+$")
        if (re.match(r"^chr(?:[1-9][0-9]?|[XYM])$", columns[0]) 
            and re.match(num_format, columns[1])
            and re.match(r"^[ATGC]$", columns[3]) 
            and re.match(r"^[ATGC]$", columns[4])): 
            return True
        else:
            return False

我检查了两个文件 - 一个应该 return True,另一个应该是 False,但是我在两个文件上都得到了 True,所以我尝试逐行进行测试,但仍然得到 True。 文件示例:

ChrX, 74226650, ., T, C, 50, ., DP=385;VDB=0;SGB=-0.693147;RPB=0.982669;MQB=1;BQB=0.947576;MQ0F=0;AC=2;AN=2;DP4=0,95,0,289;MQ=20, GT:PL:DP, 1/1:78,127,0:384

输出应该是 true 还是 false 取决于条件。

感谢任何帮助!

您需要一一解决的问题:

  • 第一列应以 chr 开头,以 1-99 之间的任意数字或字母 M,X,Y - chr(?:0?[1-9]|[1-9][0-9]|[MXY])
  • 第二列必须是大于0的所有整数 - 0*[1-9][0-9]*
  • 第4和第5列需要是下一个字母“ATCG”之一(只有一个) - [ATCG].

现在,考虑到列分隔符是您在代码示例中使用的分隔符(制表符,\t),您可以使用

def isVCF(file):
    num_format = re.compile(r"^chr(?:0?[1-9]|[1-9][0-9]|[MXY])\t0*[1-9][0-9]*\t[^\t]*(?:\t[ATCG]){2}\t", re.I)
    with open(file, "r+") as my_file:
        for line in my_file:
            if not num_format.match(line):
                return False
        return False

参见regex demo

请注意,我使用 re.I 来启用不区分大小写,因为如果您只需要匹配 Chrchr 这样,删除 re.I 并将 chr 替换为 (?i:chr).

详情:

  • ^ - 字符串开头
  • chr(第 1 列开始)- chr 字符串
  • (?:0?[1-9]|[1-9][0-9]|[MXY])(第 1 列结尾):一个可选的 0,然后是一个非零数字,或者从 19 的一个数字,然后是任何数字一个数字 (0 - 99),或来自 MXY 集合
  • 的一个字母
  • \t - 一个标签
  • 0*[1-9][0-9]*(第 2 列):零个或多个 0,一个非零数字,然后是任何零个或多个数字
  • \t - 一个标签
  • [^\t]*(第 3 列)- 制表符以外的任何零个或多个字符
  • (?:\t[ATCG]){2}(第 4 列和第 5 列)- 选项卡,来自 ATCG 集的字母,两次
  • \t - 一个标签。