Python 用正则表达式验证输入 使用RE进行验证和分类输入
这里现在使用像“1-1-A-A”这样的输入,并在每个点上加“-” 但是输入可以是多种多样的,例如“chr1-1-C-G”、“3-1-C-A”、“CHRX-34-A-T”等 第一个位置应该接受“chr1,chr2,…chr23,chrX,ChrY” ,第二个位置只接受正数,第三和第四个位置只接受{A,C,G,T}的一个字母 因此,我考虑使用“re.findall”并使用错误案例来返回错误输入的警告。但不确定如何使用正则表达式给出错误 有人能帮忙吗Python 用正则表达式验证输入 使用RE进行验证和分类输入,python,regex,Python,Regex,这里现在使用像“1-1-A-A”这样的输入,并在每个点上加“-” 但是输入可以是多种多样的,例如“chr1-1-C-G”、“3-1-C-A”、“CHRX-34-A-T”等 第一个位置应该接受“chr1,chr2,…chr23,chrX,ChrY” ,第二个位置只接受正数,第三和第四个位置只接受{A,C,G,T}的一个字母 因此,我考虑使用“re.findall”并使用错误案例来返回错误输入的警告。但不确定如何使用正则表达式给出错误 有人能帮忙吗 def _check_input(var_str)
def _check_input(var_str): # maybe better to check each input seperately
"""
Checks if the input is a valid variant string
:param var_str: string supposed to be in the format 'chr-pos-ref-alt'
:return: bool which tells wether the input is valid
"""
pattern = re.compile(
r"""([1-9]|[1][0-9]|[2][0-2]|[XY]) # the chromosome
-(\d+) # the position
-[ACGT]+ #RawDescriptionHelpFormatter,
-[ACGT]+ # alt""",
re.X,
)
if re.fullmatch(pattern, var_str) is None:
return False
else:
return True
def string_to_dict(inp):
"""
Converts a variant string into a dictionary
:param inp: string which should be a valid variant
:return: dictionary with the variants keys and values
"""
inp_list = inp.split("-")
inp_dict = {
"chr": inp_list[0],
"pos": inp_list[1],
"ref": inp_list[2],
"alt": inp_list[3],
}
return inp_dict
正则表达式非常适合检查序列的全局有效性。不幸的是,我不知道如何使用一个正则表达式实现错误检查 因此,我认为可以使用正则表达式来检查输入的完整有效性。如果它无效,那么您可以添加更多的代码来警告用户可能出现的错误
import re
def _check_input(var_str):
"""
Checks if the input is a valid variant string
:param var_str: string supposed to be in the format 'chr-pos-ref-alt'
:return: a match object
:raises: ValueError on invalid input
"""
pattern = re.compile(
r"(?:chr)?(?P<chr>[1-9]|[1][0-9]|[2][0-3]|[XY])" # the chromosome
r"-(?P<pos>\d+)" # the position
r"-(?P<ref>[ACGT])" # RawDescriptionHelpFormatter
r"-(?P<alt>[ACGT])", # alt
re.X | re.IGNORECASE,
)
match = re.match(pattern, var_str)
if not match:
_input_error_suggestion(var_str)
return match # you can access values like so match['chr'], match['pos'], match['ref'], match['alt']
def _input_error_suggestion(var_str):
parts = var_str.split('-')
if len(parts) != 4:
raise ValueError('Input should have 4 parts separated by -')
chr, pos, nucleotide1, nucleotide2 = parts
# check part 1
chr_pattern = re.compile(r'(?:chr)?([1-9]|[1][0-9]|[2][0-3]|[XY])', re.IGNORECASE)
if not re.match(chr_pattern, chr):
raise ValueError('Input first part should be a chromosome chr1, chr2, ..., chr 23, chrX, chrY')
# check part 2
try:
p = int(pos)
except ValueError:
raise ValueError('Input second part should be an integer')
if p < 0:
raise ValueError('Input second part should be a positive integer')
# check part 3 and 4
for i, n in enumerate((nucleotide1, nucleotide2)):
if n not in 'ACGT':
raise ValueError(f"Input part {3 + i} should be one of {{A,C,G,T}}")
# something else
raise ValueError(f"Input was malformed, it should be in the format 'chr-pos-ref-alt'")
重新导入
定义检查输入(变量str):
"""
检查输入是否为有效的变量字符串
:param var_str:字符串的格式应为'chr pos ref alt'
:return:匹配对象
:引发:无效输入上的ValueError
"""
模式=重新编译(
r“(?:chr”)(?P[1-9]|[1][0-9]|[2][0-3]|[XY])”#染色体
r“-(?P\d+)”位置
r“-(?P[ACGT])”#RawDescriptionHelpFormatter
r“-(?P[ACGT])”,#alt
re.X | re.IGNORECASE,
)
匹配=重新匹配(模式,变量)
如果不匹配:
_输入错误建议(变量str)
返回match#您可以访问诸如so match['chr']、match['pos']、match['ref']、match['alt']之类的值
定义输入错误建议(变量str):
parts=var_str.split('-'))
如果len(部件)!=4:
raise VALUE ERROR('输入应包含4个部分,以“-”分隔)
chr,pos,核苷酸1,核苷酸2=部分
#检查第1部分
chr|u pattern=re.compile(r'(?:chr)?([1-9]|[1][0-9]|[2][0-3]|[XY]),re.IGNORECASE)
如果不重新匹配(chr_模式,chr):
raise VALUERROR('输入的第一部分应该是染色体chr1,chr2,…,chr 23,chrX,chrY')
#检查第2部分
尝试:
p=int(pos)
除值错误外:
raise VALUERROR('输入第二部分应为整数')
如果p<0:
raise VALUERROR('输入第二部分应为正整数')
#检查第3部分和第4部分
对于枚举中的i,n((核苷酸1,核苷酸2)):
如果n不在“ACGT”中:
raise VALUERROR(f“输入部分{3+i}应该是{{A,C,G,T}}之一”)
#别的
raise VALUERROR(f“输入格式不正确,应为'chr pos ref alt'”格式)
旁注:
我改进了原来的正则表达式
- 添加可选的“chr”
- 命名组
- 每个核苷酸只有一个字母
- 修复缺失的23号染色体和
- 允许不区分大小写
[2][0-3]
而不是[2][0-2]
,因为“第一个位置应该接受”chr1,chr2。。。chr 23“@Dionys不习惯使用stackflowsorry@WiktorStribiżew实际上想要调整使用re.filndall而不是使用“Split”“嘿@dionys谢谢你的评论。非常感谢。关于代码的简短问题。有没有其他不使用“split”函数的方法?如何使用它编写py.test?split有什么问题?关于py.test,您可以编写带有预成型输入的函数,您知道输出,并测试它是否引发正确的错误或正确通过。