我正在尝试生成Python正则表达式字符串以验证列的值,该列是由三个字母(大写)字母数字代码(例如)组成的唯一的三个字母代码的逗号分隔序列。该列表看起来像['XA1', 'CZZ', 'BT9', 'WFF',...]
。因此有效的列值可以是XA1
,XA1;CZZ
或XA1;BT9;WFF;
等。代码不能在序列中出现多次。
有效序列必须是非空的,由唯一的代码组成,并且可能以;
结尾,也可能不以codes
结尾,包括序列仅包含一个代码的情况。
如果match_str = '?'.join(['({};){}'.format(code, '?' if codes[-1] == code else '') for code in codes])
是代码列表,则我以此为基础构造的正则表达式匹配字符串为
'(XA1;)?(CZZ;)?(BT9;)?(WFF;)?'
使用上面仅包含四个代码的示例列表,这给了我
re.match(match_str, 'XA1;')
re.match(match_str, 'XA1;WFF')
re.match(match_str, 'XA1;')
regex匹配查询的确会产生应为有效序列的非空匹配对象,例如
In [124]: re.match(match_str, 'anystring')
Out[124]: <_sre.SRE_Match object; span=(0, 0), match=''>
In [125]: re.match(match_str, '')
Out[125]: <_sre.SRE_Match object; span=(0, 0), match=''>
In [126]: re.match(match_str, 'XA1;something')
Out[126]: <_sre.SRE_Match object; span=(0, 4), match='XA1;'>
等
if re.match(match_str, val):
# do something
else:
# do something else
我希望上面所有三个查询的结果都为空,因此我可以使用条件过滤掉无效值,例如
RuntimeExceptions
答案 0 :(得分:1)
在您希望使具有重复块的字符串失败的情况下,应避免使用正则表达式。
使用“常规” Python:
codes = ['XA1', 'CZZ', 'BT9', 'WFF']
strs = ['XA1', 'XA1;CZZ', 'XA1;BT9;WFF;', 'XA1;XA1;', 'XA1;something']
for s in strs:
chunks = s.strip(';').split(';')
if set(chunks).issubset(codes) and len(chunks) == len(set(chunks)):
print("{}: Valid!".format(s))
else:
print("{}: Invalid!".format(s))
注释:
chunks = s.strip(';').split(';')
-删除前导/尾随;
,并用;
分割字符串if set(chunks).issubset(codes) and len(chunks) == len(set(chunks)):
-检查我们获得的所有块是否都是codes
的子集,并确保chunks
中的每个项目都是唯一的。正则表达式解决方案-请勿在生产中使用!
import re
codes = ['XA1', 'CZZ', 'BT9', 'WFF']
block = "(?:{})".format("|".join(codes))
rex = re.compile( r"^(?!.*\b(\w+)\b.*\b\1\b){0}(?:;{0})*;?$".format(block) )
print(rex)
strs = ['XA1', 'XA1;CZZ', 'XA1;BT9;WFF;', 'XA1;XA1;', 'XA1;something']
for s in strs:
if rex.match(s):
print("{}: Valid!".format(s))
else:
print("{}: Invalid!".format(s))
请参见Python demo
答案 1 :(得分:0)
这是一种通用的非正则表达式解决方案,用于检查字符串是否是;
分隔的唯一/非重复代码/令牌序列(来自固定的此类令牌集)。字符串中的令牌可以采用任何顺序,但是任何令牌都只能出现一次,并且字符串可以以;
结尾或可以不以{'AR', 'CA', 'GB', 'HK', 'IN', 'US'}
结尾。字符串中的每个标记也不得包含任何空格。
示例:让令牌集为两个字母的国家代码(例如AR;CA
)的集合或子集。然后,在此问题的上下文中,“有效”字符串可以是诸如HK;US;CA;GB;
,US
,HK;
,AR;CA
之类的字符串,而无效字符串可以是诸如{{ 1}},AR;something;HK;
,something;AR;GB;US
等
def is_valid_token_sequence(s, tokens, sep=';'):
s_tokens = [t for t in s.split(sep) if t]
token_cntr = collections.Counter(s_tokens).values()
return not (
any(t not in tokens for t in s_tokens) or
any(v > 1 for v in token_cntr)
)
>>> is_valid_token_sequence('AR;CA', codes)
>>> True
>>> is_valid_token_sequence('HK;US;CA;GB;', codes)
>>> True
>>> is_valid_token_sequence('IN', codes)
>>> True
>>> is_valid_token_sequence('HK;', codes)
>>> True
>>> is_valid_token_sequence(' AR;CA', codes)
>>> False
>>> is_valid_token_sequence('1234;AR;X1;IN;CA', codes)
>>> False
>>> is_valid_token_sequence('X1;AR;GB;US', codes)
>>> False