【问题标题】:using Python re to check a string使用 Python re 检查字符串
【发布时间】:2021-03-12 05:49:10
【问题描述】:

我有一个 ID 列表,我需要检查这些 ID 的格式是否正确。正确的格式如下:

[O,P,Q][0-9][A-Z,0-9][A-Z,0-9][A-Z,0-9][0-9]    
[A-N,R-Z][0-9][A-Z][A-Z,0-9][A-Z,0-9][0-9]  
A-N,R-Z][0-9][A-Z][A-Z,0-9][A-Z,0-9][0-9][A-Z][A-Z,0-9][A-Z,0-9][0-9]

字符串后面也可以跟一个破折号和一个数字。我的代码有两个问题:1)如何将字符串的长度限制为搜索词指定的字符数? 2)如果匹配,我如何指定字符串后面可以有一个“-[0-9]”?

potential_uniprots=['D4S359N116-2', 'DFQME6AGX4', 'Y6IT25', 'V5PG90', 'A7TD4U7ZN11', 'C3KQY5-V']
import re
def is_uniprot(ID):
    status=False
    uniprot1=re.compile(r'\b[O,P,Q]{1}[A-Z,0-9]{1}[A-Z,0-9]{1}[A-Z,0-9]{1}[0-9]{1}\b')
    uniprot2=re.compile(r'\b[A-N,R-Z]{1}[0-9]{1}[A-Z,0-9]{1}[A-Z,0-9]{1}[0-9]{1}\b')
    uniprot3=re.compile(r'\b[A-N,R-Z]{1}[0-9]{1}[A-Z]{1}[A-Z,0-9]{1}[A-Z,0-9]{1}[0-9]{1}[A-Z]{1}[A-Z,0-9]{1}[A-Z,0-9]{1}[0-9]{1}\b')
    if uniprot1.search(ID) or uniprot2.search(ID)or uniprot3.search(ID):
        status=True
    return status
correctIDs=[]
for prot in potential_uniprots:
    if is_uniprot(prot) == True:
        correctIDs.append(prot)
print(correctIDs)

【问题讨论】:

  • 这能回答你的问题吗? Regex to match words of a certain length
  • 这能回答你的问题吗? stackoverflow.com/questions/4007302/…
  • 您可以在字符类中省略{1} 和逗号(如果您不想匹配逗号)它们本身的模式不包含量词并且有单词边界。因此,在这些单词边界之间,您已经匹配了准确数量的字符。要匹配可选的连字符和数字,您可以使用可选的非捕获组(?:-[0-9])?
  • @Thefourthbird 请看我的回答。我指出您的评论是我回答的“表达式修复”部分的功劳。如果您希望我更改任何内容或删除整个部分,请告诉我。

标签: python regex


【解决方案1】:

表达式修复:

阅读前:
表达式修复的所有功劳归于The fourth bird 的评论。请在此处或原始帖子下方查看该评论:

您可以省略字符类中的{1} 和逗号(如果您不想匹配逗号)它们本身的模式不包含量词并且具有单词边界。因此,在这些单词边界之间,您已经匹配了准确数量的字符。要匹配可选的连字符和数字,可以使用可选的非捕获组(?:-[0-9])?

您不需要, 分隔方括号中的字符,因为方括号指示正则表达式应匹配方括号中的所有 个字符。例如,[A-Z,0-9] 之类的正则表达式将匹配 大写字符逗号数字,而诸如 @ 之类的正则表达式987654326@ 将匹配 大写字符数字。此外,您不需要{1},因为如果未指定量词,则默认情况下正则表达式将匹配 one。这意味着您可以从表达式中删除{1}

检查长度?

有一种不用正则表达式的简单方法,如下:

string = "Q08F88"
status = (len(string) == 6 or len(string) == 8) 

但您也可以强制正则表达式匹配某些长度,使用您已经完成的\b(字边界)。您也可以在表达式的开头和结尾分别使用^$ 来表示字符串的开始结束

考虑这个表达式:^abcd$(仅匹配包含 abcd 的字符串,不包含其他内容)
这意味着它只会匹配字符串:

abcd

而不是:

eabcd
abcde

这是因为^ 表示字符串的开头,$ 表示字符串的结尾。

最后,你只剩下第一个表达式:

(^[OPQ][0-9][A-Z0-9][A-Z0-9][A-Z0-9][0-9](?:-[0-9])?$)

您可以轻松修改其他表达式,因为它们遵循与上述相同的结构。

代码建议

您的代码看起来不错,但您可以进行一些小修复以提高可读性和约定。例如,您可以更改:

if uniprot1.search(ID) or uniprot2.search(ID)or uniprot3.search(ID):
   status=True
return status

到这里:

return (uniprot1.search(ID) or uniprot2.search(ID)or uniprot3.search(ID))

# -OR-

stats = (uniprot1.search(ID) or uniprot2.search(ID)or uniprot3.search(ID))
return status

因为uniprot1.search(ID) or uniprot2.search(ID)or uniprot3.search(ID) 永远不会返回除TrueFalse 之外的任何内容,因此返回该表达式是安全的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-28
    • 2023-04-06
    • 2010-12-07
    相关资源
    最近更新 更多