Когда вопрос слишком сложен для регулярного выражения?

Исключение нулевого указателя генерируется, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:

  1. Вызов метода экземпляра объекта null.
  2. Доступ или изменение поля объекта null.
  3. Принимая длину null, как если бы это был массив.
  4. Доступ или изменение слотов null, как если бы это был массив.
  5. Бросок null как будто это было значение Throwable.

Приложения должны бросать экземпляры этого класса, чтобы указать на другие незаконные использования объекта null.

Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html

20
задан Sebastian Zartner 16 April 2015 в 20:30
поделиться

13 ответов

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

9
ответ дан 29 November 2019 в 22:54
поделиться

Несколько вещей высматривать:

  1. обнаружение начального и завершающего тэга - подобранное соединение
  2. рекурсия
  3. необходимость пойти назад (хотя можно инвертировать строку, но это - взлом)

regexes, так, как я люблю их, не хороши в тех трех вещах. И помните, сохраняют это простым! , При попытке создать regex, который делает "все", затем , Вы, вероятно, делаете его неправильно .

13
ответ дан 29 November 2019 в 22:54
поделиться

Регулярные выражения являются текстовым представлением конечные автоматы . То есть они ограничены только нерекурсивным соответствием. Это означает, что у Вас не может быть понятия "объема" или "подсоответствия" в Вашем regexp. Рассмотрите следующую проблему:

(())()

весь открытый parens, соответствовавший завершению paren?

, Очевидно, когда мы смотрим на это как люди, мы можем легко видеть, что ответ - "да". Однако никакое регулярное выражение не сможет надежно ответить на этот вопрос. Чтобы сделать этот вид обработки, Вам будет нужно полное автомат с магазинной памятью (как DFA со стеком). Это обычно найдено под маской синтаксического анализатора, такого как сгенерированные ANTLR или Бизоном.

14
ответ дан 29 November 2019 в 22:54
поделиться

То, к чему это сводится, использует здравый смысл. Если то, чему Вы пытаетесь соответствовать, становится неуправляемым, регулярным выражением монстра затем Вы или должно разбить его в небольшие, логические подрегулярные выражения, или необходимо начать заново продумать решение.

Берут адреса электронной почты (согласно Вашему примеру). Это простое регулярное выражение (взятый от приятеля RegEx) соответствует 99% всех электронных писем там:

\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b

Это коротко и к точке, и Вы будете редко сталкиваться с проблемами с ним. Однако как автор приятеля RegEx указывает, если Ваш адрес электронной почты будет в редком домене верхнего уровня ".museum", то он не будет принят.

Для верного соответствия всем адресам электронной почты необходимо придерживаться стандарта, известного как RFC 2822 . Это обрисовывает в общих чертах множество способов, которыми могут быть отформатированы адреса электронной почты, и это чрезвычайно сложно.

Вот демонстрационное регулярное выражение, пытающееся придерживаться RFC 2822:

(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"
(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x
0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9]
(?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.)
{3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08
\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])

Это, очевидно, становится проблемой убывающей доходности. Лучше использовать легко сохраняемую реализацию, которая соответствует 99% адресов электронной почты по сравнению с чудовищным, который принимает 99,9% из них.

Регулярные выражения являются большим инструментом, чтобы иметь на Вашей панели инструментов программистов, но они не решение всех Ваших проблем парсинга. При нахождении решения RegEx, начинающего стать чрезвычайно сложными, необходимо или попытаться логически разбить его в меньшие регулярные выражения для соответствия частям текста, или необходимо начать смотреть на другие методы для решения проблемы. Точно так же существуют просто проблемы, которые Регулярные выражения, из-за их характера, не могут решить (как один сказанный плакат, не придерживаясь Регулярный язык ).

7
ответ дан 29 November 2019 в 22:54
поделиться

Регулярные выражения подходят для маркирования, нахождения или идентификации отдельных битов текста, например, нахождения ключевых слов, строк, комментариев, и т.д. в исходном коде.

Регулярные выражения не подходят для определения отношений между несколькими битами текста, например, нахождения блока исходного кода с правильно парными фигурными скобками. Вам нужен синтаксический анализатор для этого. Синтаксический анализатор может использовать регулярные выражения для маркирования входа, в то время как сам синтаксический анализатор определяет, как различные соответствия regex совмещаются.

По существу, Вы идете в далеко с Вашими регулярными выражениями, если Вы начинаете думать о "балансирующихся группах" (функция вычитания группы получения.NET) или "рекурсия" (Perl 5.10 и PCRE).

6
ответ дан 29 November 2019 в 22:54
поделиться

Вот хорошая кавычка от Raymond Chen:

не заставляют регулярные выражения сделать то, в чем они не хороши. Если Вы хотите соответствовать простому шаблону, то соответствуйте простому шаблону. Если Вы хотите сделать математику, то сделайте математику. Как комментатор Maurits выразился, "Прием не должен проводить время, разрабатывая молоток/отвертку комбинации, но просто использовать молоток и отвертку.

Источник

4
ответ дан 29 November 2019 в 22:54
поделиться

Верный признак, чтобы прекратить использовать regexps является этим: если Вы носите много группирующихся брекетов' ()' и много альтернатив '|' затем, это - верный признак, который Вы пытаетесь сделать (комплекс) парсинг с регулярными выражениями.

Добавляют к расширениям Perl соединения, обратным ссылкам, и т.д. и скоро у Вас есть самостоятельно синтаксический анализатор, который трудно прочитать, трудно изменить, и трудно рассуждать об это - свойства (например, есть ли вход, над которым этот синтаксический анализатор будет работать в экспоненциальное время).

Это - время, чтобы остановить regexing и начать анализировать (с синтаксическим анализатором ручной работы, парсерами-генераторами или синтаксическим анализатором combinators).

3
ответ дан 29 November 2019 в 22:54
поделиться

Решите проблему с regex, затем дайте ее кому-то еще сведущему в regexes. Если они не могут сказать Вам, что это делает (или, по крайней мере, скажите с уверенностью, что они понимают) приблизительно за 10 минут, это слишком сложно.

3
ответ дан 29 November 2019 в 22:54
поделиться

Наряду с огромными выражениями, существуют основные ограничения на слова, которые могут быть обработаны regexp. Например, Вы не можете не записать regexp для слова, описанного n символами a, затем n символы b, где n может быть любым, более строго alt text .

На различных языках regexp является расширением Регулярный язык , но время парсинга может быть чрезвычайно большим, и этот код является непортативным.

2
ответ дан 29 November 2019 в 22:54
поделиться

Проблема слишком сложна для регулярных выражений, когда ограничения проблемы могут измениться после того, как решение записано. Так, в Вашем примере, как можно быть уверены, адрес электронной почты допустим, когда у Вас нет доступа к целевой почтовой системе, чтобы проверить, что адрес электронной почты присоединен к действительному пользователю? Вы не можете.

0
ответ дан 29 November 2019 в 22:54
поделиться

Каждый раз, когда Вы не можете быть уверены, что это действительно решает проблему, например:

  • HTML, анализирующий
  • почтовая проверка
  • синтаксические анализаторы Языка

Особенно поэтому, когда там уже существуют инструменты, которые решают проблему полностью понятным способом.

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

Это идет вне технических ограничений regexes (регулярные языки + расширения), предел пригодности для обслуживания и удобочитаемости превзойден намного ранее, чем технический предел в большинстве случаев.

1
ответ дан 29 November 2019 в 22:54
поделиться

Это может звучать глупым, но я часто оплакиваю неспособность сделать тип БД запросов с помощью регулярного выражения. Теперь особенно больше затем прежде, потому что я ввожу те типы строки поиска все время на поисковых системах. его очень трудное, если не невозможный искать +complex AND +"regular expression"

, Например, как я ищу в emacs команды, которые имеют и Буфер и Окно на их имя? Я должен искать отдельно .*Buffer.*Window and .*Window.*Buffer

-1
ответ дан 29 November 2019 в 22:54
поделиться

Мой предел является шаблоном Regex, это - приблизительно 30-50 символов в длину (варьирующийся в зависимости от того, сколько фиксированный текст и сколько команды regex)

-1
ответ дан 29 November 2019 в 22:54
поделиться
Другие вопросы по тегам:

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