Проблема с сопоставлением регулярных выражений с тестовой строкой

#regex

Вопрос:

у меня проблема, и я ее не понимаю.

Мое Регулярное выражение:

Регулярное выражение

Моя Тестовая строка:

Тестовая строка

У меня есть две проблемы и один общий вопрос 🙂

  1. Как вы можете видеть в моей Тестовой строке, самый последний (немецкий) номер телефона (большой желтый во вложении тестовой строки) неправильно соответствует моему шаблону регулярных выражений. Я не понимаю, в чем здесь проблема? «0049» соответствует группе 5, но должно соответствовать группе 2, почему это так?
  2. Моя вторая проблема заключается в том, как я могу избавиться от пробелов до и после каждого матча? (7 желтых маленьких кружочков в приложении к тестовой строке)

Для целей копирования/вставки снова приведите регулярное выражение и тестовую строку:

Регулярное выражение:
(( d{2}|00d{2})?([ ])?(()?(d{2,4})())?([-| |/])?(d{3,})([ ])?(d )?([ ])?(d )?)

Test-String: Vorwahl 089, die E.123 ebenfalls , also (089) 1234567. Die DIN 5008, также 49 89 1234567 соответственно 0049 89 1234567. Die E.123 empfiehlt, also 49 89 123456 0 respectivly 0049 89 123456 0 oder 49 89 123456 789. Также 49 89 123 456 789. Klammern 089/1234567 und 0151 19406041. Испытание 49 151 123 456 789 соответственно 0049 151 123 456 789

И последнее, но не менее важное, мой общий вопрос: является ли хорошим подходом группировать каждую логическую часть, как я сделал в своем примере?

Последняя информация: Я проверяю свое регулярное выражение с помощью https://regex101.com/ и используйте его в Python с модулем re.

Комментарии:

1. Пожалуйста, убедитесь, что шаблоны регулярных выражений на скриншоте и копия-вставка совпадают. Некоторые, кажется, отсутствуют.

2. спасибо за обратную связь, я ее исправил.

3. для вашей проблемы 1, потому что 0049 предваряется пробелом.

4. как это исправить? mybe выпуск 1 и выпуск 2 связаны 🙂

5. Кстати, [] это набор символов, который соответствует любому литеральному значению внутри, поэтому [-| |/] совпадают - , | , / и пробел, вам не нужен | внутри набора, если вы не хотите соответствовать литералу | .

Ответ №1:

То, что делает его непредсказуемым, — это многочисленные необязательные группы (..)? .

В качестве первого шага я рекомендую заменить ([ ])?(d )? как связанное выражение ([ ]?d )? , которое позволит избежать пробелов в конце совпадения — ваша точка № 2.

В качестве второго шага я рекомендую связать первое необязательное пространство с выражением «национальный набор»: (( |00)d{2}([ ])?)? . Теперь нам повезло, потому что это решает как пробел в начале, так и распознавание целого числа из-за меньшего количества возможных вариантов сопоставления.

Новое выражение теперь выглядит так:

 ((( |00)d{2}([ ])?)?(()?(d{2,4})())?([-| |/])?(d{3,})([ ]?d )?([ ]?d )?)
 

Теперь я рекомендую упростить последнюю часть, если вам не нужны отдельные групповые значения:

 ((( |00)d{2}([ ])?)?(()?(d{2,4})())?([-| |/])?(d{3,})([ ]?d ){0,2})
 

Для повышения производительности я предлагаю вам удалить родительские элементы/группы, где это возможно, или пометить их как не захватывающие, если вам не нужны конкретные значения групп.
В некоторых языках программирования вам не понадобится большинство внешних родительских имен, так как это всегда группа 0.

Комментарии:

1. Большое спасибо, для меня это прекрасно работает. «Кроме того, вам не понадобится большинство внешних парентезов, так как это всегда группа 0.» —> Это кажется важным, потому что Python не возвращает никаких результатов, если там нет большинства внешних парентезов.

2. Извините, Python возвращает результаты, но не все совпадение, а группы в виде кортежа. Поэтому мне нужно, чтобы первая группа была на весь матч. Поэтому мне нужна первая группа как целое совпадение, чтобы я мог получить к ней доступ через индекс 0 из списка результатов

3. Ладно, я не знаю насчет Питона. Отредактировал мой ответ.