I have had luck with this modern (using TEXTJOIN and TEXTSPLIT) but basic Excel formula where RegexExtract, VBA, or SQL where not available or optimal alternatives.
If cell A1 contains a text string with a 10-digit phone number, this formula will look for the last occurrence of the number 10 billion, or smaller, and format it as a phone number with dashes.
=IFERROR(
TEXT(
LOOKUP(
10^10 , MID(
TEXTJOIN(
"" , 1 , TEXTSPLIT(
A1 , { "(" , ")" , "-" , " " , "." } , , 1
)
),
ROW(
INDIRECT(
"1:" & LEN(
TEXTJOIN(
"" , 1 , TEXTSPLIT(
A1 , { "(" , ")" , "-" , " " , "." } , , 1
)
)
)
-9 )
),
10 )
+0 ),
"???-???-????" ),
"-" )
LOOKUP in the array syntax requires that the dataset be sorted. This wasn't a significant issue for my use case as the text strings that I ran through this formula typically contained only one 10-digit phone number.
The TEXTJOIN and TEXTSPLIT functions scrub all common phone number punctuation by converting the parentheses, dashes, and spaces into column separators, then rejoining the reduced string.
INDIRECT is used to determine the string length after all punctuation has been scrubbed. We subtract 9 from this length because a 10-digit string cannot start less than 10-characters from the end of the string. ROW provides MID with potential starting points for the 10-digit string within the full, scrubbed and re-joined text string.
TEXT formats the resultant string as a phone number with area code, segmented with hyphens.