我需要在Python中,根据四个原子组成的一组字符串,根据相关的字典进行取值,字符串的格式是这样的:‘A-B-C-D’,
其中ABCD分布是四个原子的原子类型,每个原子用一个或者两个字符进行表示,比如‘OP-P-OS-CA’这样,原子之间用‘-’进行连接。
然后我需要根据一个字典进行对各个字符串进行取值,字典的key也是同样类型的字符串,但是带通配符,例如:
‘X-C-CX-X’
‘X-CI-CT-X‘
‘X-C5-N*-X‘
‘X-C5-NB-X‘
‘X-C-C4-X‘
‘X-CA-C4-X‘
‘X-C4-C4-X‘
‘X-C4-CT-X‘
‘X-C4-N*-X‘
‘CT-OS-CT-CI‘
‘H1-CI-CT-OS‘
‘H1-CI-CT-OH‘
在这里,单独的X表示可以是任意原子,注意只有单独的X才是通配符,比如CX这种就不是,CX就是一种特定的原子类型。
此外,星号(*)也算是合法的原子类型字符,比如N*这种,这导致我本来想用正则表达式写的,但因为水平有限,这种情况我不知道怎么写了。
还有一点,四个原子的连接顺序是可逆的,比如‘H1-CI-CT-OH‘和‘OH-CT-CI-H1‘是等价的。
那么这种情况除了在双重循环中挨个原子进行比较之外,有没有什么简单的方法直接进行取值呢?
字典是什么样子的,截个图吧
你的字典里的键存在重复匹配的可能:比如 ‘X-CI-CT-X‘ 和 ‘H1-CI-CT-OS‘,如果我理解得没错的话,你是要先进行最长匹配查找字典,如果找不到,再进行通配符匹配查找。
按照这个逻辑来,先进行字符串的完全匹配查找,如果找不到,则把字符串首尾两段的字符替换成“X”再进行查找。
替换的方法比较简单,下面举例把 ‘H1-CI-CT-OS‘ 变成 ‘X-CI-CT-X‘
a = 'H1-CI-CT-OS'
b = ['X'] + a.split('-')[1:-1] + ['X']
c = '-'.join(b)
如果需要逆序查找,则需要增加一步,把字符串按照“-”拆分,然后倒序再用“-”连在一起组成逆序字符串进行查找,不过看你的例子,‘H1-CI-CT-OH‘和‘OH-CI-CT-H1‘ 好像只有首尾两个原子交换位置,并不是完全逆序,这样的话只要在拆分的列表里交换首尾的元素再重新组合即可。
最后,如果你想用正则的话,使用反斜线加星号(\*)转义,就可以匹配星号这个符号了
你题目的解答代码如下:
import re
def search(dic,s):
res = []
s2 = '-'.join(reversed(s.split('-')))
for key,v in dic.items():
# KEY转成正则表达式,*替换成\* .并且前后加^$
kg = r"^" + key.replace('*',r'\*') + r"$"
# 单独的 X 替换成 .+
reg = re.sub(r'(?<=-|\^)X(?=-|\$)',r'.+',kg)
# print(reg)
if re.match(reg,s) or re.match(reg,s2):
res.append(v)
return res
dic={
'X-C-CX-X': 111,
'X-CI-CT-X':222,
'X-C5-N*-X':333,
'H1-CI-CT-OS':444,
'H1-CI-CT-OH':555
}
print(search(dic,"A-C-CX-T"))
print(search(dic,"ED-CT-CI-T"))
print(search(dic,"GF-C5-N*-G5"))
如有帮助,请点击我的回答下方的【采纳该答案】按钮帮忙采纳下,谢谢!
s = '''
‘X-C-CX-X’
‘X-CI-CT-X‘
‘X-C5-N*-X‘
‘X-C5-NB-X‘
‘X-C-C4-X‘
‘X-CA-C4-X‘
‘X-C4-C4-X‘
‘X-C4-CT-X‘
‘X-C4-N*-X‘
‘CT-OS-CT-CI‘
‘H1-CI-CT-OS‘
‘H1-CI-CT-OH‘
'''
reg_set = set()
abcd_list = re.findall(r"([A-Z0-9*]+?)-([A-Z0-9*]+?)-([A-Z0-9*]+?)-([A-Z0-9*]+)", s)
for item in abcd_list:
print('提取出ABCD=>',item[0],item[1], item[2], item[3])
reg = '-'.join([re.sub('^X$','[A-Z0-9]{1,2}',_).replace('*','[A-Z0-9]') for _ in item])
reg_set.add(reg)
print('key正则表达式=>',reg)
按你的意思key带通配符,那么可以用正则表达式字符串来代替,到时你搜索的时候只要能用该正则式search出结果就能提取出来了
为了下一步提取出来ABCD都加括号了,ABCD对应为search.group(1)、search.group(2)、search.group(3)、search.group(4)
例如:
第一个X-C-CX-X是([A-Z0-9]{1,2})-(C)-(CX)-([A-Z0-9]{1,2}),则A-C-CX-A和B-C-CX-B都是符合的
第三个X-C5-N*-X是([A-Z0-9]{1,2})-(C5)-(N[A-Z0-9])-([A-Z0-9]{1,2}),则A-C5-NA-A和A-C5-NB-A都符合