Скрываем часть номера телефона

в 3:46, , рубрики: javascript, Phone, regexp, Регулярные выражения

Представьте, что вам нужно скрыть часть номер под звездочками. Заменить +79999999999 на +799****9999 не трудно, а теперь представьте, что масок номеров не одна, а на много больше, номера эти как российские, так и канадские или любые другие. В этой функции я постарался захватить как можно больше номеров.

Является строка номером телефона:

/^((?+?d{1,2})? ?(?d{1,3})? ?d+-? ?d+-? ?d+)$/

Кушает:
'+7 999 999-99-99',
'+79999999999',
'79999999999',
'+7 (495) 150 41-32',
'+55 11 99999-5555',
'(+44) 0848 9123 456',
'+1 284 852 5500',
'+1 345 9490088',
'+32 2 702-9200',
'+65 6511 9266',
'+86 21 2230 1000',
'(123) 456 7899',
'123-456-7899',
'123 456 7899',
'1234567899',
'1 800 5551212',
'800 555 1212',
'8005551212',
'18005551212',
'234-911-5678',
'+54 9 2982 123456',
'02982 15 123456',
'(719) 309-3829'

Функция замены:

function hideNumber(string, replaceTo = '*', elemsHide = 4, sliceFromback = 4) {
    result = string.match(/^((?+?d{1,2})? ?(?d{1,3})? ?d+-? ?d+-? ?d+)$/);
    if (result !== null) {
          // тут мы выдергиваем n элементов после среза x
        const regex = new RegExp(`((\(?\ ?\-?\d\ ?\-?\)?){${elemsHide}})((\ ?\-?\d\ ?\-?){${sliceFromback}}$)`, 'gm');

        let m;
        while ((m = regex.exec(string)) !== null) {
            if (m.index === regex.lastIndex) {
                regex.lastIndex++;
            }

            const forRex = m[1];
            const str = m[1].replace(/(d)/gm, replaceTo);
            const lasts = m[3];
            const full = string;
            const noBack = full.slice(0, -lasts.length).slice(0, -forRex.length);
            const out = noBack+''+str+''+lasts;
            return out;
        }
        return string;
    } else {
        return string;
    }
}

Демо

const str = [
    '+7 999 999-99-99',
    '+79999999999',
    '79999999999',
    '+7 (495) 150 41-32',
    '+55 11 99999-5555',
    '(+44) 0848 9123 456',
    '+1 284 852 5500',
    '+1 345 9490088',
    '+32 2 702-9200',
    '+65 6511 9266',
    '+86 21 2230 1000',
    '(123) 456 7899',
    '123-456-7899',
    '123 456 7899',
    '1234567899',
    '1 800 5551212',
    '800 555 1212',
    '8005551212',
    '18005551212',
    '234-911-5678',
    '+54 9 2982 123456',
    '02982 15 123456',
    '(719) 309-3829',
    'Judi'
];


str.forEach(i => {
    console.log(i +' => '+hideNumber(i));
})

console:
+7 999 999-99-99 => +7 99* ***-99-99
+79999999999 => +799****9999
79999999999 => 799****9999
+7 (495) 150 41-32 => +7 (49*) *** 41-32
+55 11 99999-5555 => +55 11 9****-5555
(+44) 0848 9123 456 => (+44) 084* ***3 456
+1 284 852 5500 => +1 28* *** 5500
+1 345 9490088 => +1 34* ***0088
+32 2 702-9200 => +32 * ***-9200
+65 6511 9266 => +65 **** 9266
+86 21 2230 1000 => +86 21 **** 1000
(123) 456 7899 => (12*) *** 7899
123-456-7899 => 12*-***-7899
123 456 7899 => 12* *** 7899
1234567899 => 12****7899
1 800 5551212 => 1 80* ***1212
800 555 1212 => 80* *** 1212
8005551212 => 80****1212
18005551212 => 180****1212
234-911-5678 => 23*-***-5678
+54 9 2982 123456 => +54 9 29** **3456
02982 15 123456 => 02982 ** **3456
(719) 309-3829 => (71*) ***-3829
Judi => Judi

Если один из ваших номеров (который мог бу существовать на деле) не подошел, пишите, дополню.

PS
В комментарии mwizard добавил реализацию без регулярки

type Context = {
    readonly offset: number;
    readonly filtered: string;
}

function hidePhone(phone: string): string {
    return Array.from(phone).reduceRight((ctx: Context, char: string): Context => {
        const isDigit = char >= '0' && char <= '9';
        const offset = ctx.offset + (isDigit ? 1 : 0);
        const filteredChar = isDigit ? (offset >= 4 && offset < 8) ? '*' : char : char;
        const filtered = filteredChar + ctx.filtered;
        return { offset, filtered };
    }, { offset: -1, filtered: '' }).filtered;
}

Автор: Александр

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js