У меня есть сценарий Python, который мы используем для анализа файлов CSV с введенными пользователем номерами телефонов, поэтому существует довольно много странных форматов / ошибок.Нам нужно разбить эти номера на отдельные компоненты, а также исправить некоторые распространенные ошибки при вводе.
Наши номера телефонов указаны для Сиднея, Мельбурна (Австралия) или Окленда (Новая Зеландия), указанных в международном формате.
Наш стандартный номер в Сиднее выглядит следующим образом:
+61(2)8328-1972
У нас есть международный префикс +61
, за которым следует код области из одной цифры в скобках, 2
, за которыми следуют две половинылокального компонента, разделенного дефисом, 8328-1972
.
Мельбурнские цифры просто имеют 3 вместо 2 в коде города, например
+61(3)8328-1972
Оклендские числа похожи, ноони содержат 7-значный локальный компонент (3, а затем 4 цифры) вместо обычных 8 цифр.
+64(9)842-1000
У нас также есть совпадения для ряда распространенных ошибок.Я разделил выражения регулярных выражений на их собственный класс.
class PhoneNumberFormats():
"""Provides compiled regex objects for different phone number formats. We put these in their own class for performance reasons - there's no point recompiling the same pattern for each Employee"""
standard_format = re.compile(r'^\+(?P<intl_prefix>\d{2})\((?P<area_code>\d)\)(?P<local_first_half>\d{3,4})-(?P<local_second_half>\d{4})')
extra_zero = re.compile(r'^\+(?P<intl_prefix>\d{2})\(0(?P<area_code>\d)\)(?P<local_first_half>\d{3,4})-(?P<local_second_half>\d{4})')
missing_hyphen = re.compile(r'^\+(?P<intl_prefix>\d{2})\(0(?P<area_code>\d)\)(?P<local_first_half>\d{3,4})(?P<local_second_half>\d{4})')
space_instead_of_hyphen = re.compile(r'^\+(?P<intl_prefix>\d{2})\((?P<area_code>\d)\)(?P<local_first_half>\d{3,4}) (?P<local_second_half>\d{4})')
У нас есть одно для чисел standard_format, затем другие для различных распространенных случаев ошибок, например, добавление дополнительного нуля перед кодом области (02
вместо2), or missing hyphens in the local component (e.g.
83281972 instead of
8328-1972`) и т. Д.
Затем мы вызываем их каскадно, если / elifs:
def clean_phone_number(self):
"""Perform some rudimentary checks and corrections, to make sure numbers are in the right format.
Numbers should be in the form 0XYYYYYYYY, where X is the area code, and Y is the local number."""
if not self.telephoneNumber:
self.PHFull = ''
self.PHFull_message = 'Missing phone number.'
else:
if PhoneNumberFormats.standard_format.search(self.telephoneNumber):
result = PhoneNumberFormats.standard_format.search(self.telephoneNumber)
self.PHFull = '0' + result.group('area_code') + result.group('local_first_half') + result.group('local_second_half')
self.PHFull_message = ''
elif PhoneNumberFormats.extra_zero.search(self.telephoneNumber):
result = PhoneNumberFormats.extra_zero.search(self.telephoneNumber)
self.PHFull = '0' + result.group('area_code') + result.group('local_first_half') + result.group('local_second_half')
self.PHFull_message = 'Extra zero in area code - ask user to remediate.'
elif PhoneNumberFormats.missing_hyphen.search(self.telephoneNumber):
result = PhoneNumberFormats.missing_hyphen.search(self.telephoneNumber)
self.PHFull = '0' + result.group('area_code') + result.group('local_first_half') + result.group('local_second_half')
self.PHFull_message = 'Missing hyphen in local component - ask user to remediate.'
elif PhoneNumberFormats.space_instead_of_hyphen.search(self.telephoneNumber):
result = PhoneNumberFormats.missing_hyphen.search(self.telephoneNumber)
self.PHFull = '0' + result.group('area_code') + result.group('local_first_half') + result.group('local_second_half')
self.PHFull_message = 'Space instead of hyphen in local component - ask user to remediate.'
else:
self.PHFull = ''
self.PHFull_message = 'Number didn\'t match recognised format. Original text is: ' + self.telephoneNumber
Моя цель - сделать сопоставление как можно более тесным, но все же, по крайней мере, выявляем типичные ошибки.
Существует ряд проблем с тем, что я сделал выше:
- Я использую
\d{3,4}
, чтобы соответствовать первомуполовина местного компонента.В идеале, однако, мы действительно хотим поймать 3-значную первую половину , если , если это новозеландский номер (т.е. начинается с +64(9)
).Таким образом, мы можем пометить номера в Сиднее / Мельбурне, в которых отсутствует цифра.Я мог бы выделить auckland_number в его собственный шаблон регулярных выражений в PhoneNumberFormats
, однако это означает, что он не будет перехватывать новозеландское число в сочетании с ошибками (extra_zero, missing_hyphen, space_instead_of_hyphen).Поэтому, если я не воссоздаю их версию только для Окленда, например, auckland_extra_zero, которая кажется бессмысленно повторяющейся, я не могу понять, как легко это исправить. - Мы не подбираем комбинации ошибок - например, если они имеютдополнительный ноль и пропущенный дефис, мы не будем поднимать это.Есть ли простой способ сделать это с помощью регулярных выражений, без явного создания перестановок различных ошибок?
Я хотел бы решить две вышеупомянутые проблемы и, надеюсь, немного их исправить, чтобы что-то перехватить.что я пропустилЕсть ли более умный способ сделать то, что я пытался сделать выше?
Приветствия, Виктор
Дополнительные комментарии:
Ниже просто приведем некоторый контекст:
Этот сценарий предназначен для глобальной компании с одним офисом в Сиднее, одним в Мельбурне и одним в Окленде.
Цифры взяты из внутреннего списка сотрудников Active Directory (т.е. это не клиентсписок, но наши собственные офисные телефоны).
Следовательно, мы не ищем общий австралийский сценарий сопоставления телефонных номеров, скорее, мы ищем общий сценарий для анализа номеров из трех конкретных офисов.В общем, должны отличаться только последние 4 цифры.
Мобильные телефоны не требуются.
Сценарий предназначен для анализа дампа CSV в Active Directory и переформатирования номеров вприемлемый формат для другой программы (QuickComm)
Эта программа от внешнего поставщика, для которой требуются числа в точном формате, который я создал в приведенном выше коде - поэтому числа выпали, как 0283433422.
Сценарий, который я написал, не может изменить записи, он работает только с их дампом CSV - записи хранятся в Active Directory, и единственный способ получить к ним доступ, чтобы исправить их, - этонапишите сотруднику по электронной почте и попросите его войти в систему и изменить свои собственные записи.
Таким образом, этот скрипт запускается PA, чтобы произвести вывод, требуемый этой программой.Она / он также получит список людей, которые имеют неправильно отформатированные числа - отсюда и сообщения о том, что пользователь просит исправить.Теоретически их должно быть немного.Затем мы отправляем по электронной почте / звоним этим сотрудникам, прося их исправить свои записи - скрипт запускается один раз в месяц (цифры могут меняться), нам также необходимо пометить новых сотрудников, которым также удалось ввести свои записи неправильно.1068 * @ Джон Маклин: Вы рекомендуете ли я удалять регулярные выражения и просто пытаться извлечь цифры конкретной позиции из строки?
Я искал способ отловить типичные случаи ошибок в комбинациях (напримерпробел вместо дефиса в сочетании с дополнительным нулем), но разве это не так просто?