const regex = /(?i)(?=(\d)\d)(?<![\d\-\x{2013}\x{2014}%])(?!000|666|9\d\d|\d{3}00|\d{5}0000|\1{9}|012345678|123456789|234567890|098765432|876543210|078051120|219099999)\d{9}(?![\d\-\x{2013}\x{2014}%])(?!\.(?:pdf|docx?|xlsx?|pptx?|zip|jpe?g|png|txt|log)\b)/gm;
// Alternative syntax using RegExp constructor
// const regex = new RegExp('(?i)(?=(\\d)\\d)(?<![\\d\\-\\x{2013}\\x{2014}%])(?!000|666|9\\d\\d|\\d{3}00|\\d{5}0000|\\1{9}|012345678|123456789|234567890|098765432|876543210|078051120|219099999)\\d{9}(?![\\d\\-\\x{2013}\\x{2014}%])(?!\\.(?:pdf|docx?|xlsx?|pptx?|zip|jpe?g|png|txt|log)\\b)', 'gm')
const str = `################
## Must match:
################
009958881
123454891 is my ssn
my ssn is 123454891
my ssn is 123454891 ok?
my ssn is 123454891.
my ssn is:123454891.
# This one sneaks though, but we can live with that, maybe?
myssnnumberis123454891ok?
################
## Must not match:
################
# All-Zero group sequences
231840000
231007289
000877289
# Starting with 9
908780485
# Starting with 666
666780485
# Same number sequences:
222222222
555555555
# Ascending/Descending sequences:
123456789
87654321
# Known invalidated SSN:
219099999
078051120
# File names with common extensions:
123454891.pdf
123454891.xlsx
Check the attachment: 123454891.xls, then get back to me.
Check the attachment: 123454891.jpeg, then get back to me.
# Extra digits:
1123454891
1234548911
# Unsupported boundaries:
–123454891
—123454891
%123454891
123454891-
123454891—
123454891%
1-123454891
123454891-1
# Valid SSN with separators:
123-45-4891
098-18-6564
123-45-4848
702-02-0202
001-14-0004
009 95 8881
123-45-4891 is my ssn
my ssn is 123-45-4891
my ssn is 123-45-4891 ok?
my ssn is 123-45-4891.
123 45 4891 is my ssn
my ssn is 123 45 4891
my ssn is 123 45 4891 ok?
my ssn is 123 45 4891.
my ssn is:123-45-4891.
my ssn is:123 45 4891.
ss#123-45-4891
ssn123-45-4891
# Emdash separator:
123–45–4891
# Endash separator:
123—45—4891
# Slash separator
123/45/4891
# Telephone
1-234-567-8901
1-234-567-8901
1-234-567-8901
1 (234) 567-8901
12347658901
# Credit card
5500 0000 0000 0004
3400 0000 0000 009
3000 0000 0000 04
5500-1244-2232-0004
3400-1244-0000-009
3000-1244-1234-04
# Random Numbers
1234567890112371298739872891738912738937289d712897381297381927d3128937893d7218947d1892742189duc89789v127c897412987893c12893c79
122-426-389
187-5-43212
187-0-43212
2423-45-6789
# Unsupported boundaries:
ssn-123-45-4891
123-45-4891-ssn
`;
// Reset `lastIndex` if this regex is defined globally
// regex.lastIndex = 0;
let m;
while ((m = regex.exec(str)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
// The result can be accessed through the `m`-variable.
m.forEach((match, groupIndex) => {
console.log(`Found match, group ${groupIndex}: ${match}`);
});
}
Please keep in mind that these code samples are automatically generated and are not guaranteed to work. If you find any syntax errors, feel free to submit a bug report. For a full regex reference for JavaScript, please visit: https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions