Я могу оптимизировать этот телефон-regex?

Очень неясно, что вы хотите, но IIUC:

print(np.array([arr1[i:i + 15] for i in range(0, len(arr1), 15)]))
9
задан Paul Peelen 14 May 2013 в 11:39
поделиться

5 ответов

Первое наблюдение: чтение regex является кошмаром. Это жить не может без/x режима Perl.

Второе наблюдение: существуют партии, и партии и большое получение круглых скобок в выражении (42, если я рассчитываю правильно; и 42, конечно, "Ответ на Жизнь, Вселенную, и Все" - видит Douglas Adams "Руководство Hitchiker по Галактике" при необходимости в в объясненном).

Тарифицируйте Ящерицу, отмечает, что Вы используете'(-)?( )?'несколько раз. Нет никакого очевидного преимущества для этого по сравнению с'-? ?'или возможно'[- ]?', если Вы не действительно полны решимости относительно получения фактической пунктуации отдельно (но существует столько круглых скобок получения, удающихся, какие объекты '$n' использовать были бы трудны).

Так, давайте попытаемся редактировать копию Вашей остроты:

( |^|>)
(
    ((((((\+|00)(31|32)( )?(\(0\))?)|0)([0-9]{2})(-)?( )?)?)([0-9]{7})) |
    ((((((\+|00)(31|32)( )?(\(0\))?)|0)([0-9]{3})(-)?( )?)?)([0-9]{6})) |
    ((((((\+|00)(31|32)( )?(\(0\))?)|0)([0-9]{1})(-)?( )?)?)([0-9]{8}))
)
( |$|<)

Хорошо - теперь мы видим регулярную структуру Вашего регулярного выражения.

Существует намного больше анализа, возможного отсюда. Да, могут быть значительные улучшения регулярного выражения. Первое, очевидное, нужно извлечь часть международного префикса, и применить это однажды (дополнительно или потребовать начального нуля), и затем примените национальные правила.

( |^|>)
(
    (((\+|00)(31|32)( )?(\(0\))?)|0)
    (((([0-9]{2})(-)?( )?)?)([0-9]{7})) |
    (((([0-9]{3})(-)?( )?)?)([0-9]{6})) |
    (((([0-9]{1})(-)?( )?)?)([0-9]{8}))
)
( |$|<)

Затем мы можем упростить пунктуацию, как отмечено прежде, и раскрыть некоторые правдоподобно избыточные скобки и улучшить устройство распознавания кода страны:

( |^|>)
(
    (((\+|00)3[12] ?(\(0\))?)|0)
    (((([0-9]{2})-? ?)?)[0-9]{7}) |
    (((([0-9]{3})-? ?)?)[0-9]{6}) |
    (((([0-9]{1})-? ?)?)[0-9]{8})
)
( |$|<)

Мы можем заметить, что regex не осуществляет правила о кодах мобильного телефона (таким образом, он не настаивает, что '06' сопровождается 8 цифрами, например). Это также, кажется, позволяет 1, 2 или 3 кода 'обмена' цифры быть дополнительным, даже с международным префиксом - вероятно, не, что Вы имели в виду, и фиксация, которая раскрывает еще некоторые скобки. Мы можем раскрыть еще больше скобок после этого, ведя к:

( |^|>)
(
    (((\+|00)3[12] ?(\(0\))?)|0)    # International prefix or leading zero
    ([0-9]{2}-? ?[0-9]{7}) |        # xx-xxxxxxx
    ([0-9]{3}-? ?[0-9]{6}) |        # xxx-xxxxxx
    ([0-9]{1}-? ?[0-9]{8})          # x-xxxxxxxx
)
( |$|<)

И можно разработать дальнейшую оптимизацию отсюда, я надеялся бы.

12
ответ дан 4 December 2019 в 07:49
поделиться

(31|32) выглядит плохо. При соответствии 32, regex механизм сначала попытается соответствовать 31 (2 символа), сбой, и отследить в обратном порядке два символа для соответствия 31. Более эффективно сначала соответствовать 3 (один символ), попробовать 1 (сбой), отследить в обратном порядке один символ и соответствовать 2.

Конечно, Ваш regex перестал работать на 0800-числах; они не 10 цифр.

3
ответ дан 4 December 2019 в 07:49
поделиться

Разделите его на несколько выражений. Например (псевдокод)...

phone_no_patterns = [
    /[0-9]{13}/, # 0031201234567
    /+(31|32)\(0\)\d{2}-\d{7}/ # +31(0)20-1234567
    # ..etc..
]
def check_number(num):
    for pattern in phone_no_patterns:
        if num matches pattern:
            return match.groups

Затем Вы просто циклично выполняетесь по каждому шаблону, проверяя, соответствует ли каждый..

Разделение шаблонов делает свое легкое для фиксации определенных чисел, которые вызывают проблемы (который был бы ужасен с единственным монолитным regex),

3
ответ дан 4 December 2019 в 07:49
поделиться

Господь Чертовски, какая путаница!:) Если у Вас есть высокоуровневые семантические или бизнес-правила (такие как те, Вы описываете разговор о европейских числах, числах в Нидерландах, и т.д.), Вы были бы, вероятно, лучше обслужены, повредив, который единственные regexp тестируют в несколько отдельных тестов regexp, один для каждого из Ваших правил высокого уровня.

if number =~ /...../  # Dutch mobiles
  # ...
elsif number =~ /..../  # Belgian landlines
  # ...
# etc.
end

Будет вполне немного легче считать и поддержать и изменить тот путь.

8
ответ дан 4 December 2019 в 07:49
поделиться

Это не оптимизация, но Вы используете

(-)?( )?

три раза в Вашем regex. Это заставит Вас соответствовать по номерам телефона как они

+31(0)6-12345678
+31(0)6 12345678

но будет также соответствовать числам, содержащим тире, сопровождаемого пространством, как

+31(0)6- 12345678

Можно заменить

(-)?( )?

с

(-| )?

соответствовать или тире или пространству.

2
ответ дан 4 December 2019 в 07:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: