使用正则表达式从文本中提取特定字母并与字典进行比较

2024-10-01 07:43:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个90%的文本列表,格式是AABBB-CCCDDD001。在这个列表中,也有一些文本可能包括

AABBBICS-CCCDDD001 or 
AABBBIGW-CCCDDD001 or 
AABBBRTL-CCCDDD001 or 
AABBBTDZ-CCCDDD001

这些设备的名称

AA - country code
BBB - site code
CCC - Function code
DDD - Sub Function code.

例如:USNYCRTL-LANDCE001

如果代码ICS、IGW、RTL或TDZ与文本中的匹配,我希望它输出它们各自的编号,为此我创建了一个字典:

ENVIRONMENTCODE = {
    'ICS': '1',
    'IGW': '2',
    'RTL': '3',
    'TDZ': '4'
}

NULLCODE = {
    'NULL': '9'
}

所以,如果文本是:

AABBBICS-CCCDDD001 it should print '1' or 
AABBBIGW-CCCDDD001 it should print '2' or 
AABBBRTL-CCCDDD001 it should print '3' or 
AABBBTDZ-CCCDDD001 it should print '4'

上面的例子:USNYCRTL-LANDCE001应该打印“3”,因为RTL对应于字典中的数字“3”

现在,对于格式为AABBB-CCCDDD001的90%文本,应该打印“9”,因为它应该与键“NULL”配对。而且,可能很少有文本可以包含AABBBXYZ-CCCDDD001,但是我们需要忽略XYZ,因为它不在字典中,而只考虑字典中的那些。并将该文本标记为“9”。你知道吗

我知道regex可以在这里使用,但我正处于学习python的早期阶段,regex现在似乎对我来说遥不可及。这就是我迄今为止所尝试的:

def environmentcode(self):
    idx = self.name.find('-')
    if idx > -1:
        if self.name in ENVIRONMENTCODE:
            return ENVIRONMENTCODE
        else:
            return NULLCODE
    else:
        return "Not Found"

它只打印空码字典,而不管文本中是否有键。谁能帮我一下吗。你知道吗


Tags: or文本self列表return字典格式code
3条回答

我们可以使用.find获取码字(如果存在),然后使用字典将码字映射到它的代码号。我们可以使用dictionary.get方法返回缺失或未知码字的空代码。如果遇到错误数据,此版本将返回None:名称不包含'-',或者名称在'-'之前没有8或5个字母。你知道吗

env_code = {
    'ICS': '1',
    'IGW': '2',
    'RTL': '3',
    'TDZ': '4',
}

null_code = '9'

def get_env_code(name):
    idx = name.find('-')
    if idx == 8:
        # code may be valid
        code = name[idx-3:idx]
    elif idx == 5:
        # code is missing
        code = ''
    else:
        # Bad name
        return None

    return env_code.get(code, null_code)

# test

data = [
    'AABBBICS-CCCDDD001',
    'AABBBIGW-CCCDDD001',
    'AABBBRTL-CCCDDD001',
    'AABBBTDZ-CCCDDD001',
    'USNYCRTL-LANDCE001',
    'AABBBXYZ-CCCDDD001',
    'AABBB-CCCDDD001',
    'BADDATA',
]

for s in data:
    print(s, get_env_code(s))

输出

AABBBICS-CCCDDD001 1
AABBBIGW-CCCDDD001 2
AABBBRTL-CCCDDD001 3
AABBBTDZ-CCCDDD001 4
USNYCRTL-LANDCE001 3
AABBBXYZ-CCCDDD001 9
AABBB-CCCDDD001 9
BADDATA None

下面是一个更简单的版本,它返回空代码,而不是针对坏数据的None。你知道吗

def get_env_code(name):
    idx = name.find('-')
    code = name[idx-3:idx] if idx == 8 else ''
    return env_code.get(code, null_code)

如果您只是检查在每个测试字符串中是否找到ENVIRONMENTCODE的成员,那么就不需要regex。只需使用python关键字in,例如

ENVIRONMENTCODE = {
    'ICS': '1',
    'IGW': '2',
    'RTL': '3',
    'TDZ': '4'
}

NULLCODE = {
    'NULL': '9'
}

def environment_code(test_string, code_dict):
    if '-' not in test_string:
        return 'no dash'
    for code, value in code_dict.items():
        if code in test_string:
            return value
    return NULLCODE['NULL']


to_test = ['AABBBICS-CCCDDD001',
           'AABBBIGW-CCCDDD001',
           'AABBBRTL-CCCDDD001',
           'AABBBTDZ-CCCDDD001']
for test_str in to_test:
    print(environment_code(test_str, ENVIRONMENTCODE))

原始代码的问题在于

test_string in code_dict

它只检查被测字符串和字典中的键之间的精确匹配。你知道吗

我的建议是:

def environmentcode(s):
    if "-" not in s:  #(**)
        return None   #(**)
    h,t=s.split("-")
    code=h.strip()[5:]
    return ENVIRONMENTCODE.get(code,9)   

data="AABBBICS-CCCDDD001 AABBBIGW-CCCDDD001 AABBBRTL-CCCDDD001 AABBBTDZ-CCCDDD001 USNYCRTL-LANDCE001 AABBB-CCCDDD001 something"

for s in data.split():
    print(s," >",environmentcode(s))

Output:
AABBBICS-CCCDDD001  > 1
AABBBIGW-CCCDDD001  > 2
AABBBRTL-CCCDDD001  > 3
AABBBTDZ-CCCDDD001  > 4
USNYCRTL-LANDCE001  > 3
AABBB-CCCDDD001  > 9
something  > None

#                            -
# Filtering text with regex. In this case, (**) not needed.
text="""AABBBICS-CCCDDD001 Alice was beginning to get very tired of sitting by her sister on the bank... AABBBIGW-CCCDDD001 AABBBRTL-CCCDDD001 AABBBTDZ-CCCDDD001 USNYCRTL-LANDCE001 AABBB-CCCDDD001 AABBBXYZ-CCCDDD001 something"""

import re

data= re.findall(r"\b[A-Z]{5,8}-[A-Z]{6}001\b",text)
for s in data:
    print(s," >",environmentcode(s))

相关问题 更多 >