Комментарии 20
Если один из ваших номеров (который мог бу существовать на деле) не подошел, пишите, дополню.
Спасибо, но лучше я сам у себя проверю и если понадобится — исправлю.
“У вас есть проблема. Вы решили использовать регулярные выражения чтобы её решить. Теперь у вас две проблемы.”
Обычно телефонные номера проходят валидацию, так что все равно к какому-то определенному формату приводить надо. Ну и хранить в БД "как юзер ввёл" тоже, на мой взгляд, не очень кошерно.
Но как пример сферического коня в вакууме, вполне нарм.
Оооо! «Мама, я постиг простенькие регулярки.» Не нужно так, этот код потом людям придется сопровождать.
- Откусили голову (если есть) по шаблону
/(?<=+|\A)\d+(?=\D)/
- Выбросили все, что не цифра — из того, что осталось.
- Добавили код страны (если п. 1 вернул значение), или дефолт.
Две строчки кода, внятные и короткие.
По-вашему это номер телефона: (+12 (123 456 789-000
+380 57 700 0046
(Укртелеком, г. Харьков, Украина)Код города может быть больше чем 3 цифры:
+7 (86196) 7-19-86
(Россельхозбанк, г. Тихорецк, Краснодарский край, Россия)type Context = {
readonly offset: number;
readonly filtered: string;
}
function hidePhone(phone: string, replaceTo = '*', elemsHide = 4, sliceFromback = 4): string {
const rangeStart = sliceFromback;
const rangeEnd = sliceFromback + elemsHide;
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 >= rangeStart && offset < rangeEnd) ? replaceTo : char;
const filtered = filteredChar + ctx.filtered;
return { offset, filtered };
}, { offset: -1, filtered: '' }).filtered;
}
console.log(hidePhone('+12(345) 678-90-12 ;D'));
phoneNumber.replace(/\d/g, (current) => {
this.counter = this.counter || 0;
this.counter++;
return (this.counter > 3 && this.counter < 7) ? '*' : current
}
)
Вместо 3 и 7 можете вставлять какие-то свои min и max.
Так проще, но по условиям нужно идти с обратной стороны.
phoneNumber.split('').reverse().join('').replace(/\d/g, (current) => {
this.counter = this.counter || 0;
this.counter++;
return (this.counter > 3 && this.counter < 7) ? '*' : current
}
).split('').reverse().join('');
Хотя смысл это имеет разве что эзотерический. Что значит ваш комментарий про обратную сторону?
Я только сейчас обратил внимание на вашу дописку к комментарию. "Идти с обратной стороны" значит, что если у вас последовательность варьруемой длины (то 8 знаков, то 15), вам всегда нужно оставить последние 4 цифры целыми, и закрасить еще 4 цифры с конца.
Впрочем, с эзотерическим смыслом соглашусь, т.к. если уж хранить ненормализованные данные, так нефильтрованные, а раз фильтровать, так все равно нужно предварительно нормализовать.
Вики подсказывает, что форматов телефонов очень много и там все сложно, а значит регулярки выкидываем на свалку и делаем простой LL парсер. А ещё лучше — libphonenumber.
Лет 10 назад аутсорсили для одного российского сотового оператора плагины для IE, FF, Outlook. Задача была находить на странице телефонные номера, подсвечивать их, добавлять флажок и пару кнопок.
Так вот, сначала пробовали регулярками. Но тестировщики постоянно находили примеры где регулярки не работают. Потом я плюнул и написал обычную функцию на js, как когда-то в универе на си делал. Заработало, причём на порядок быстрее регулярок (на тестовой странице было 100+ номеров с разным контентом).
Ещё достаточно нетривиальной задачей было определение страны по номеру телефона. Во-первых разные форматы номеров, как локальных так и международных. Во-вторых, коды стран от 1 до 4 цифр (см. Википедию). США с Канадой где номера могут на +1 начинаться и т.п.
Хороший вариант — оставлять последние две цифры, как делают некоторые крупные сайты (конкретно инстаграм сейчас вспомнился).
Кроме того из номера следует убрать всё кроме цифр.
В такой постановке — это будет существенно более простая задача.
Скрываем часть номера телефона