python - 正则表达式匹配一个以分号分隔的标记序列的字符串
问题描述
我正在尝试生成一个 Python 正则表达式字符串来验证一列的值,该列是三字母(大写)字母数字代码列表中以逗号分隔的唯一三字母代码序列,例如 . 列表看起来像['XA1', 'CZZ', 'BT9', 'WFF',...]
. 因此有效的列值可以是XA1
、XA1;CZZ
或XA1;BT9;WFF;
等。一个代码不能在序列中出现多次。
有效序列必须是非空的,由唯一的代码组成,并且可能以也可能不以 a 结尾;
,包括序列仅包含一个代码的情况。
如果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;')
等等
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
解决方案
在像您这样的情况下,应该避免使用正则表达式,您希望使具有重复块的字符串失败。
使用“常规”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))
在线查看Python 演示。
注意事项:
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))
推荐阅读
- mysql - WHERE NOT IN 返回一个空集,而它不应该
- json - 解码错误:typeMismatch“预期解码数组
而是找到了一本字典。” - java - 为 Couchbase 设置 ComboPooledDataSource 驱动程序时,驱动程序名称是什么?
- java - 在 java 上触发流数据帧和累加器
- javascript - 当我在 nodeJS 中将代码作为 python shell 运行时,如何永久安装 python 包?
- java - 询问jetty如何嵌入maven中
- javascript - 如何在 oracle jet datepicker 中设置一周的第一天
- python - 如何将数据图添加到 Python 中的现有图表?
- java - 如何使用 java 14 使用 Java Web Start?
- node.js - 从反应上传文件到firebase失败