python - 正则表达式匹配以分号分隔的标记序列的字符串

标签 python regex

我正在尝试生成一个 Python 正则表达式字符串来验证列的值,这些值是来自三字母(大写)字母数字代码列表的逗号分隔的唯一三字母代码序列,例如 .该列表类似于 ['XA1', 'CZZ', 'BT9', 'WFF',...]。因此有效的列值可以是 XA1XA1;CZZXA1;BT9;WFF; 等。代码不能出现在序列中 more不止一次。

有效序列必须是非空的,由唯一代码组成,并且可以或不可以以 ; 结尾,包括序列仅包含一个代码的情况。

如果 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

最佳答案

在像您这样的情况下,应避免使用正则表达式,因为您希望使具有重复 block 的字符串失败。

使用“常规”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 demo online .

注意事项:

  • chunks = s.strip(';').split(';') - 删除前导/尾随 ; 并用 ;< 拆分字符串
  • if set(chunks).issubset(codes) and len(chunks) == len(set(chunks)): - 检查我们获得的所有 block 是否都是 的子集编码并确保 block 中的每个项目都是唯一的。

正则表达式解决方案 - 不要在生产中使用!

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

关于python - 正则表达式匹配以分号分隔的标记序列的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56754034/

相关文章:

python - pandas:日期/值的数据帧 -> "biggest value so far"的数据帧?

c++ - 使用 MSVC 2013 的正则表达式错误

regex - R:找到字符串中的最后一个点

ruby 正则表达式字符串$

python - 为什么 numpy.polyfit 大幅偏离?

Python 记录多模块记录器在主程序之外不工作

python - 如何在 SciPy 中绘制粗的抗锯齿线?

python - 无法在 Python API 中为新的 Google Cloud Platform 项目启用计费

javascript - 在 TinyMCE 中自动将两个破折号转换为 —

javascript - 匹配特定单词的正则表达式模式