Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit af78987

Browse files
authored
Update phone_normalize.sql
1 parent ee9d0e5 commit af78987

File tree

1 file changed

+26
-7
lines changed

1 file changed

+26
-7
lines changed

‎functions/phone_normalize.sql‎

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
-- TODO add support for https://datatracker.ietf.org/doc/html/rfc3966 (see https://habr.com/ru/post/278345/)
22

33
create or replace function phone_normalize(
4-
country_code int,
5-
area_code text,
6-
local_number text
4+
country_code int,--код страны в любом формате или NULL
5+
area_code text,--код зоны в любом формате или NULL
6+
local_number text--локальный номер телефона в любом формате или NULL
77
)
88
returns text
99
immutable
1010
--returns null on null input
1111
parallel safe
1212
language plpgsql
13+
cost 10
1314
as
1415
$$
1516
declare
1617
phone text;
18+
is_starts_with_plus boolean;
1719
begin
1820
-- not valid speed improves
1921
if country_code not between 0 and 999
@@ -23,6 +25,8 @@ begin
2325
return null;
2426
end if;
2527

28+
is_starts_with_plus := country_code is null and concat_ws('', area_code, local_number) ~ '^\D*?\+';
29+
2630
area_code := trim(regexp_replace(area_code, '(?:^\D+|\D+$|[ ()\-.]+|&(?:ndash|minus);)', ' ', 'g'));
2731
local_number := trim(regexp_replace(local_number, '(?:^\D+|\D+$|[ ()\-.]+|&(?:ndash|minus);)', ' ', 'g'));
2832

@@ -52,12 +56,14 @@ begin
5256
phone := replace(phone, '/', '');
5357
--raise notice 'stage 2: %', phone;
5458

59+
/* --DEPRECATED
5560
if phone ~ '(\d)1円{8}' --все цифры одинаковые
5661
then
5762
return null;
5863
end if;
64+
*/
5965

60-
if country_code is null and octet_length(phone) = 10
66+
if country_code is null and octet_length(phone) = 10and not is_starts_with_plus
6167
then
6268
phone = '7' || phone;
6369
end if;
@@ -94,7 +100,7 @@ create or replace function phone_normalize(
94100
local_number text
95101
)
96102
returns text
97-
stable
103+
immutable
98104
--returns null on null input
99105
parallel safe
100106
language sql
@@ -111,13 +117,21 @@ create or replace function phone_normalize(
111117
phone text
112118
)
113119
returns text
114-
stable
120+
immutable
115121
returns null on null input
116122
parallel safe
117123
language sql
118124
as
119125
$$
120-
select phone_normalize(null, null, phone);
126+
select
127+
case when --speed improves: номер телефона в международном формате E.164 ?
128+
left(phone, 1) = '+'
129+
and octet_length(phone)
130+
between 1/*+*/ + 8 --https://stackoverflow.com/questions/14894899/what-is-the-minimum-length-of-a-valid-international-phone-number
131+
and 1/*+*/ + 15 --https://en.wikipedia.org/wiki/E.164 and https://en.wikipedia.org/wiki/Telephone_numbering_plan)
132+
and phone ~ '^\+\d+$' then phone
133+
else phone_normalize(null, null, phone)
134+
end;
121135
$$;
122136

123137

@@ -151,7 +165,12 @@ do $$
151165
assert phone_normalize(8,'7 977','123 45 67') = '+79771234567';
152166
assert phone_normalize(7,'977','1234567') = '+79771234567';
153167
assert phone_normalize(8,null,'8 9771234567') = '+79771234567';
168+
154169
assert phone_normalize('8 977 1234567') = '+79771234567';
170+
assert phone_normalize('+79771234567') = '+79771234567';
171+
assert phone_normalize('677 1234567') = '+76771234567';
172+
assert phone_normalize('+677 1234567') = '+6771234567';
173+
assert phone_normalize('210(-.-)7905(-.-)1234567') = '+21079051234567';
155174

156175
--negative
157176
assert phone_normalize(-1,'977','1234567') is null;

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /