'Match the SSN patterns if both delimiter are same

need to match the ssn numbers only if both delimiters should match. But below code matches all.

((?:\d[-.\s]*?){9})

Input:

list of ssn are 222-33-4444, 333.77-8888 and 111 77.9998 and 111 22 3333 and 11-222222-9

Expected output:

222-33-4444
111 22 3333
11-222222-9


Solution 1:[1]

You can capture the first delimiter and then use a back-reference to assert that the second delimiter is the same character. Since the format can be variable in terms of delimiter placement, you also need to assert that there are 9 digits and 2 delimiters:

\b(?=[\d. -]{11}\b)\d{1,}([. -])\d{1,}\1\d{1,}\b

Demo on regex101

If the SSN may be adjacent to word characters, \b will not work (as there is no word boundary between a digit and a word character) and you will need to use negative lookarounds to assert the SSN is not preceded or followed by other digits:

(?<!\d)(?=[\d. -]{11}(?!\d))\d{1,}([. -])\d{1,}\1\d{1,}(?!\d)

Demo on regex101

If the SSN may have no delimiters, you can just add \d{9} (9 digits) as an alternation to the regex:

(?<!\d)(?:(?=[\d. -]{11}(?!\d))\d{1,}([. -])\d{1,}\1\d{1,}|\d{9})(?!\d)

Demo on regex101

Solution 2:[2]

There is no need for costly lookahead or lookbehind:

\d+(\D)\d+\1\d+

Since your question is tagged :

ssn.length() == 11 && ssn.matches("\\d+(\\D)\\d+\\1\\d+")

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 VGR