特定于 Spamassassin 的正则表达式帮助

Regex help specific to Spamassassin

我正在尝试为社会安全号码创建过滤器并使用以下正则表达式:

\b(?!000|666)[0-8][0-9]{2}-(?!00)[0-9]{2}-(?!0000)[0-9]{4}\b

问题是正则表达式在Spamassassin中也匹配以下类型的字符串,我一直没能解决问题。

18-007-08-9056-1462-2205

我希望它仅在 SSN 字符串独立时才匹配。示例:

18 007-08-9056 1462-2205
007-08-9056
xyz 007-08-9056
007-08-9056 xyz

您的问题是 \b 在单词边界匹配,而 - 被认为是单词边界。你可以尝试这样的事情:

(?:^|[^-\d])((?!000|666)[0-8][0-9]{2}-(?!00)[0-9]{2}-(?!0000)[0-9]{4})(?:$|[^-\d])

匹配将在 </code> 中可用。您可能能够根据您的特定类型的输入字符串找到更优雅的解决方案。 (例如,SSN 周围是否总是有空格?如果是这样,您可以使用 <code>\s,等等)

\b 断言是一个单词边界 - 它匹配从单词字符过渡到 non-word 字符的任何位置。数字是单词字符,而连字符不是。要指定空白边界,您可以使用环视:

(?<!\S)(?!000|666)[0-8][0-9]{2}-(?!00)[0-9]{2}-(?!0000)[0-9]{4}(?!\S)

这指定模式之前没有 non-space 个字符,之后也没有 non-space 个字符。环视允许您指定这一点,同时仍然匹配字符串的开头或结尾。

\b(?<![.-])(?!000|666)[0-8][0-9]{2}-(?!00)[0-9]{2}-(?!0000)[0-9]{4}\b(?![.-])

这与您的正则表达式相同,但它也排除了周围的破折号和点(随意添加到这些字符 类,但确保破折号 (-) 始终位于结束,否则它会创建一个范围)。

\b 匹配分词符。您可能知道这一点,但这意味着它的一侧(之前或之后但不是两者)必须是单词字符(字母、数字或下划线),而另一侧(之后或之前但不是两者)必须 不是是一个单词字符(它可能是一个换行符或者由于已经到达字符串的beginning/end而不存在)。你想要这个,但你也想排除更多的东西。因此:

\b(?<![.-])表示分词后,检查前一个字符(如果有的话)。它不能匹配 [.-](一个点或破折号的字符)。

\b(?![.-])表示分词后,下一个字符(如果有的话)一定不能匹配[.-].

当我说 "if any" 时,我指的是存在换行符、文件开头或文件结尾的可能性。这些都会满足这些消极的环视。

另请参阅此 full regex explanation, with examples, at regex101