【问题标题】:How can I make my pattern matching function stop reporting non-matches?如何让我的模式匹配功能停止报告不匹配?
【发布时间】:2019-08-20 09:38:48
【问题描述】:

我正在尝试编写模式匹配函数。 我想检查一个字符串是否以特定子字符串的任何“切片”结尾,然后返回一个包含布尔值和匹配字符串(如果有)的字典。

所以如果 str1 是:

ABCD

而str2是:

HDNABCD

或者str2是:

HDNSHAB

函数应该返回:

results = {'match': True, 'string': '<matching string>'}

(即使是一个以单个 A 字符结尾的字符串也应该返回 True)

而一个不匹配应该返回:

results = {'match': False, 'string': ''}

这是我目前所拥有的。

def matchpatend(str1, str2):
    '''Find any substring at the end of a string'''
    index = len(str1)
    while index > 0:
        index = index - 1
        if str2.endswith(str1):
            result = {'match': True,
                      'string': str(str1)}
            return result
        elif str2.endswith(str1[:index]):
            result = {'match': True,
                      'string': str(str1[:index])}
            return result

这是在程序主体中使用时。

adpater_seq_1 = 'GACTGCAT'
with open(fastq, 'r') as in_f_obj, open(new_file_1, 'w') as out_f_obj: 
    line_count = 0
    id_seq = ''
    base_seq = ''
    for line in in_f_obj:  # Read the fastq file line by line
        line_count += 1
        if line_count % 4 == 1:  # Find the read ID line.
            id_seq = line.rstrip()  # Store the read ID line.
        elif line_count % 4 == 2:  # Find the sequence line.
            base_seq = line.rstrip()  # Store the sequence line.

            results = matchpatend(adapter_seq_1, base_seq)
            if results['match'] is True:
                out_f_obj.write("{}\n{}\nAdapter contamination: {}\n".format(id_seq, base_seq, results['string']))
            elif results['match'] is False:
                break

代码正确输出匹配项及其匹配字符串,但它也会将带有空白字符串的不匹配项输出到输出文件。

如何阻止程序写出错误匹配项?有没有更好的方法来编写这个函数?

【问题讨论】:

  • 为什么HDNSHAB应该是真的?
  • 因为它以AB结尾,所以它应该匹配以ABCD[:2]结尾。
  • 澄清一下,您希望 any 子字符串匹配(例如 "BC""CD" 等),还是只匹配 str1[:i] 以匹配某些 i(即只有"A""AB""ABC""ABCD"),这就是您现有代码的含义?
  • 对于某些i,匹配必须是str1[:i],所以,ABCDABCABA
  • @umbro_tracksuit 好的。对了,这里if results["match"] is True是多余的,你可以直接用if results["match"]

标签: python python-3.x


【解决方案1】:

这是一个解决方案,它首先生成模式的所有前导子字符串,按长度的降序排列(因为我猜你想匹配尽可能长的子字符串?),然后遍历它们,检查每个转。

def leading_substrings(string):
    return (string[:i] for i in range(len(string), 0, -1))

def match_pattern_end(pattern, sequence):
    for sub in leading_substrings(pattern):
        if sequence.endswith(sub):
            return {"match": True, "string": sub}
    return {"match": False, "string": ""}

print(match_pattern_end("ABCD", "HDNABCD"))  # {'match': True, 'string': 'ABCD'}
print(match_pattern_end("ABCD", "HDNHABC"))  # {'match': True, 'string': 'ABC'}
print(match_pattern_end("ABCD", "HDNSHCD"))  # {'match': False, 'string': ''}
print(match_pattern_end("ABCD", "HDNSHAB"))  # {'match': True, 'string': 'AB'}
print(match_pattern_end("ABCD", "HDNSAGH"))  # {'match': False, 'string': ''}

【讨论】:

  • 您好,感谢您的帮助!对于某些i,代码需要匹配str1[:i],因此,ABCDABCABA。经过一番摆弄,我的代码正确匹配,但由于某种原因,它打印出 False 匹配以及 True 匹配。
猜你喜欢
  • 1970-01-01
  • 2021-10-28
  • 2016-10-28
  • 2021-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-28
相关资源
最近更新 更多