我有一个正则表达式,负责匹配USPS的跟踪号。有2个表达式组合在一起,如下所示:
np.histogram([len(obj.attrib) for obj in objects])
这是我要匹配的示例:
r'\b(9[0-9]{3} ?[0-9]{4} ?[0-9]{4} ?[0-9]{4} ?[0-9]{4} ?[0-9]{2}|9[0-9]{3} ?[0-9]{4} ?[0-9]{4} ?[0-9]{4} ?[0-9]{4} ?[0-9]{2} ?[a-z]{2} ?[0-9]{3} ?[0-9]{3} ?[0-9]{3} ?US)\b'
虽然字符串的第一部分显然与第一个表达式匹配,但它实际上应与第二个表达式匹配,因为这是正确的格式。第一个模式匹配,因为字符串的一半满足该模式。
处理这些类型的“误报”的最佳方案是什么?
答案 0 :(得分:3)
首先请注意,[0-9]
在大多数情况下都简化为\d
-读写起来容易得多。
当您要在两种模式之间交替,而较短的一个完全匹配 时,您可以将较长的一个放在第一位。也就是说,代替:
\b(
9\d{3} ?\d{4} ?\d{4} ?\d{4} ?\d{4} ?\d{2}
|
9\d{3} ?\d{4} ?\d{4} ?\d{4} ?\d{4} ?\d{2} ?[a-z]{2} ?\d{3} ?\d{3} ?\d{3} ?US
)\b
(领先的空格和换行符只是为了使分组更清晰)
你可以做
\b(
9\d{3} ?\d{4} ?\d{4} ?\d{4} ?\d{4} ?\d{2} ?[a-z]{2} ?\d{3} ?\d{3} ?\d{3} ?US
|
9\d{3} ?\d{4} ?\d{4} ?\d{4} ?\d{4} ?\d{2}
)\b
https://regex101.com/r/8CVhJ2/1
但是有一个更好的选择:为什么不匹配较短部分 ,然后可选匹配较长模式的其余部分:
\b
9\d{3} ?\d{4} ?\d{4} ?\d{4} ?\d{4} ?\d{2}
(?: ?[a-z]{2} ?\d{3} ?\d{3} ?\d{3} ?US)?
\b
https://regex101.com/r/8CVhJ2/2
您还可以通过在组中重复顺序的子模式\d{4} ?
来简化上述操作:
\b
9\d{3} ?(?:\d{4} ?){4}\d{2}
(?: ?[a-z]{2} ?(?:\d{3} ?){3}US)?
\b
全部一行:
\b9\d{3} ?(?:\d{4} ?){4}\d{2}(?: ?[a-z]{2} ?(?:\d{3} ?){3}US)?\b