我正在尝试为社会保险号创建一个过滤器,并使用以下正则表达式:
\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
答案 0 :(得分:2)
您的问题是\b
在单词边界处匹配,而-
被认为是单词边界。您可以尝试这样的事情:
(?:^|[^-\d])((?!000|666)[0-8][0-9]{2}-(?!00)[0-9]{2}-(?!0000)[0-9]{4})(?:$|[^-\d])
匹配将在$1
中可用。您可能可以根据您的特定类型的输入字符串找到更优雅的解决方案。 (例如,SSN周围总是会有空格吗?如果是,则可以使用\s
等)。
答案 1 :(得分:2)
\b
断言是一个单词边界-它匹配从单词字符过渡到非单词字符的任何位置。数字是单词字符,连字符不是。要指定空白边界,可以使用环视:
(?<!\S)(?!000|666)[0-8][0-9]{2}-(?!00)[0-9]{2}-(?!0000)[0-9]{4}(?!\S)
这指定在模式之前没有空格字符,在模式之后没有空格字符。环顾四周功能可让您在仍匹配字符串开头或结尾的同时进行指定。
答案 2 :(得分:0)
\b(?<![.-])(?!000|666)[0-8][0-9]{2}-(?!00)[0-9]{2}-(?!0000)[0-9]{4}\b(?![.-])
这与您的正则表达式相同,但是它也排除了周围的破折号和圆点(可以随意添加到这些字符类中,但是请确保破折号(-
)始终位于结尾处,否则它会一直会创建一个范围)。
\b
与分词符匹配。您可能知道这一点,但这意味着它的一侧(之前或之后但不能同时为两个)必须是文字字符(字母,数字或下划线),而另一侧(必须在之前或之后但并非两者都必须)< em>不是是单词字符(它可能是换行符或由于到达字符串的开头/结尾而不存在)。您想要这个,但是您也想排除其他一些东西。因此:
\b(?<![.-])
表示在单词中断后检查前一个字符(如果有)。它不能与[.-]
(单个字符,点或破折号)匹配。
\b(?![.-])
意味着分词后,下一个字符(如果有)必须与[.-]
不匹配。
当我说“如果有的话”时,是指存在换行符,文件开头或文件结尾的可能性。这些都将满足这些负面的看法。