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



我打算学习regex,并尝试使用它来解决问题。我需要编写一个函数来获得一个VCF文件,并需要检查文件中的一些列,看看它们是否符合要求。

第一列应以"chr"开头,以1-99之间的任何数字或字母"M,X,Y"之一结尾。第二列必须是所有大于0的整数。第4列和第5列需要是下一个字母"ATCG"中的一个(仅为其中一个(。如果其中一个语句即使在一行中也是错误的,那么它应该返回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

我检查了两个文件——一个应该返回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]

现在,考虑到列分隔符是您在代码示例中使用的分隔符(TAB字符,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演示。

注意,我使用re.I来启用不区分大小写,因为您在问题中同时使用了chrChr,如果您需要以这种方式仅匹配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列(:零个或多个0s,一个非零数字,然后是任何零个或更多数字
  • t-选项卡
  • [^t]*(第3列(-除制表符之外的任何零个或多个字符
  • (?:t[ATCG]){2}(第4列和第5列(-tab,来自ATCG的一个字母集,两次
  • t-一个选项卡

最新更新