Regexp вылетает на iPhone - PullRequest
       2

Regexp вылетает на iPhone

2 голосов
/ 15 декабря 2010

У меня есть регулярное выражение, которое выглядит так:

^(\+\d\d)?(?(?<=\+\d\d)((| )\(0\)(| )| |)|(0))(8|\d\d\d?)[-/ ]?\d\d( ?\d){1,4} ?\d\d$

Используется для проверки шведских телефонных номеров. В других средах, таких как .NET, это регулярное выражение работает нормально, но в Objective-c оно вызывает сбой, говоря, что регулярное выражение не является допустимым регулярным выражением. Я далеко не эксперт, когда дело доходит до регулярных выражений, поэтому мне интересно, может ли кто-нибудь помочь мне найти причину, по которой это регулярное выражение не работает.

Я использую Reggy для проверки регулярных выражений, и проблема, похоже, в этой группе

(?(?<=\+\d\d)((| )\(0\)(| )| |)|(0))

но я не могу понять, почему ... Если я удаляю (? и ) из начала и конца этой группы, сбой исчезает. Кто-нибудь знает, что делает (?? Насколько я знаю, ? используется для указания того, что группа является необязательной, но что это значит, когда она используется в самом начале группы?

Ответы [ 2 ]

2 голосов
/ 15 декабря 2010

это условие:

(?(condition)true-expression|false-expression)

и поскольку NSPredicate использует пакет регулярных выражений ICU, такие условия недоступны. См:

http://userguide.icu -project.org / строки / регулярное выражение

Вы должны использовать стороннюю библиотеку регулярных выражений.

-marc

1 голос
/ 15 декабря 2010

Я сделал ваше регулярное выражение "разборчивым", преобразовав его в многословную форму и пометив его, чтобы вы могли видеть, что он пытается сделать. Надеюсь, вы согласитесь, что в этом нет особого смысла:

^                   # Start of string
(\+\d\d)?           # Match + and two digits optionally, capture in backref 1
(?(?<=\+\d\d)       # Conditional: If it was possible to match +nn previously,
 (\s?\(0\)\s?|\s|)  # then try to match (0), optionally surrounded by spaces
                    # or just a space, or nothing; capture that in backref 2
 |                  # If it was not possible to match +nn,
 (0)                # then match 0 (capture in backref 3)
)                   # End of conditional
(8|\d\d\d?)         # Match 8 or any two-three digit combination --> backref 4
[-/\s]?             # match a -, / or space optionally
\d\d                # Match 2 digits, don't capture them
(\s?\d){1,4}        # Match 1 digit, optionally preceded by spaces; 
                    # do this 1 to 4 times, and capture only the last match --> backref 5
\s?\d\d             # Match an optional space and two digits, don't capture them
$                   # End of string

В своей текущей форме он проверяет строки вроде

+46 (0) 1234567
+49 (0) 1234567
+00 1234567
+99 08 11 1 11
01234567
012-34 5 6 7 8 90

и он не работает на строках типа

+7 123 1234567
+346 (77) 123 4567
+46 (0) 12/34 56 7

Так что я очень сомневаюсь, что он делает то, что должен. Кроме того, большинство регулярных выражений можно значительно упростить, отбросив условное выражение, которое приводит в действие вашу библиотеку регулярных выражений. Не имеет смысла оптимизировать что-то сломанное, но если ваш клиент настаивает, вот версия, которая имеет точно такую ​​же функциональность, но без условий:

^(?:\+\d\d(?: ?(?:\(0\)\s?)?)?|0)(?:8|\d\d\d?)[-/ ]?\d\d(?: ?\d){1,4} ?\d\d$
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...