Python 用正则表达式验证输入 使用RE进行验证和分类输入

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)

这里现在使用像“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):  # 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,您可以编写带有预成型输入的函数,您知道输出,并测试它是否引发正确的错误或正确通过。