处理误报正则表达式

时间:2018-11-29 00:15:18

标签: regex

我有一个正则表达式,负责匹配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'

虽然字符串的第一部分显然与第一个表达式匹配,但它实际上应与第二个表达式匹配,因为这是正确的格式。第一个模式匹配,因为字符串的一半满足该模式。

处理这些类型的“误报”的最佳方案是什么?

1 个答案:

答案 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