I have a regex that parses US phone numbers into 3 strings.
JavaScript
x
10
10
1
import re
2
s = ' 916-2221111 ' # this also works'(916) 222-1111 '
3
4
reg_ph = re.match(r'^s*(?(d{3}))?-? *(d{3})-? *-?(d{4})', s)
5
if reg_ph:
6
return reg_ph.groups()
7
8
else:
9
raise ValueError ('not a valid phone number')
10
it works perfectly on the numbers:
JavaScript
1
3
1
'(916) 222-1111 '
2
' 916-2221111 '
3
Now I need to add an additional regex to generate a Value Error for numbers such as
JavaScript
1
2
1
s = '916 111-2222' # there are white spaces between the area code and a local number and NO ')'
2
I tried
JavaScript
1
3
1
reg_ph = re.match(r'^s*(?(d{3}))?s*-? *(d{3})-? *-?(d{4})', s)
2
reg_ph = re.match(r'^s*(?(d{3}))?s*-? *(d{3})-? *-?(d{4})', s)
3
but non rejects the string in question
I will greatly appreciate any ideas. I am very new to Regex!
Advertisement
Answer
In Python re you could use a conditional to check for group 1 having the opening parenthesis.
If that is the case match the closing parenthesis, optional spaces and 3 digits. Else match -
and 3 digits.
If you use re.match you can omit ^
JavaScript
1
2
1
^s*(()?d+(?(1))s*d{3}|-d{3})-?d{4}
2
If you want to match the whole string and trailing whitespace chars:
JavaScript
1
2
1
^s*(()?d+(?(1))s*d{3}|-d{3})-?d{4}s*$
2
In parts, the pattern matches:
^
Start of strings*
Match optional whitespace chars(()?
Optional group 1, match(
d+
Match 1+ digits(?
Conditional(1))s*d{3}
If group 1 exist, match the closing)
, optional whitespace chars and 3 digits|
Or-?
Match optional –d{3}
Match 3 digits
)
close conditional-?d{4}
Match optional – and 4 digits
See a regex demo
For example, using capture groups in the pattern to get the digits:
JavaScript
1
13
13
1
import re
2
3
strings = [' (916) 111-2222',' 916-2221111 ', '916 111-2222']
4
pattern =r's*(()?(d+)(?(1))s*(d{3})|-(d{3}))-?(d{4})s*$'
5
6
for item in strings:
7
m=re.match(pattern, item)
8
if m:
9
t = tuple(s for s in m.groups() if s is not None and s.isdigit())
10
print(t)
11
else:
12
print("no match for " + item)
13
Output
JavaScript
1
4
1
('916', '111', '2222')
2
('916', '222', '1111')
3
no match for 916 111-2222
4