Исключение нулевого указателя генерируется, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:
null
. null
. null
, как если бы это был массив. null
, как если бы это был массив. null
как будто это было значение Throwable. Приложения должны бросать экземпляры этого класса, чтобы указать на другие незаконные использования объекта null
.
Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html
Когда необходимо проанализировать выражение, это не определяется регулярный язык .
Несколько вещей высматривать:
regexes, так, как я люблю их, не хороши в тех трех вещах. И помните, сохраняют это простым! , При попытке создать regex, который делает "все", затем , Вы, вероятно, делаете его неправильно .
Регулярные выражения являются текстовым представлением конечные автоматы . То есть они ограничены только нерекурсивным соответствием. Это означает, что у Вас не может быть понятия "объема" или "подсоответствия" в Вашем regexp. Рассмотрите следующую проблему:
(())()
весь открытый parens, соответствовавший завершению paren?
, Очевидно, когда мы смотрим на это как люди, мы можем легко видеть, что ответ - "да". Однако никакое регулярное выражение не сможет надежно ответить на этот вопрос. Чтобы сделать этот вид обработки, Вам будет нужно полное автомат с магазинной памятью (как DFA со стеком). Это обычно найдено под маской синтаксического анализатора, такого как сгенерированные ANTLR или Бизоном.
То, к чему это сводится, использует здравый смысл. Если то, чему Вы пытаетесь соответствовать, становится неуправляемым, регулярным выражением монстра затем Вы или должно разбить его в небольшие, логические подрегулярные выражения, или необходимо начать заново продумать решение.
Берут адреса электронной почты (согласно Вашему примеру). Это простое регулярное выражение (взятый от приятеля 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, начинающего стать чрезвычайно сложными, необходимо или попытаться логически разбить его в меньшие регулярные выражения для соответствия частям текста, или необходимо начать смотреть на другие методы для решения проблемы. Точно так же существуют просто проблемы, которые Регулярные выражения, из-за их характера, не могут решить (как один сказанный плакат, не придерживаясь Регулярный язык ).
Регулярные выражения подходят для маркирования, нахождения или идентификации отдельных битов текста, например, нахождения ключевых слов, строк, комментариев, и т.д. в исходном коде.
Регулярные выражения не подходят для определения отношений между несколькими битами текста, например, нахождения блока исходного кода с правильно парными фигурными скобками. Вам нужен синтаксический анализатор для этого. Синтаксический анализатор может использовать регулярные выражения для маркирования входа, в то время как сам синтаксический анализатор определяет, как различные соответствия regex совмещаются.
По существу, Вы идете в далеко с Вашими регулярными выражениями, если Вы начинаете думать о "балансирующихся группах" (функция вычитания группы получения.NET) или "рекурсия" (Perl 5.10 и PCRE).
Вот хорошая кавычка от Raymond Chen:
не заставляют регулярные выражения сделать то, в чем они не хороши. Если Вы хотите соответствовать простому шаблону, то соответствуйте простому шаблону. Если Вы хотите сделать математику, то сделайте математику. Как комментатор Maurits выразился, "Прием не должен проводить время, разрабатывая молоток/отвертку комбинации, но просто использовать молоток и отвертку.
Верный признак, чтобы прекратить использовать regexps является этим: если Вы носите много группирующихся брекетов' ()' и много альтернатив '|' затем, это - верный признак, который Вы пытаетесь сделать (комплекс) парсинг с регулярными выражениями.
Добавляют к расширениям Perl соединения, обратным ссылкам, и т.д. и скоро у Вас есть самостоятельно синтаксический анализатор, который трудно прочитать, трудно изменить, и трудно рассуждать об это - свойства (например, есть ли вход, над которым этот синтаксический анализатор будет работать в экспоненциальное время).
Это - время, чтобы остановить regexing и начать анализировать (с синтаксическим анализатором ручной работы, парсерами-генераторами или синтаксическим анализатором combinators).
Решите проблему с regex, затем дайте ее кому-то еще сведущему в regexes. Если они не могут сказать Вам, что это делает (или, по крайней мере, скажите с уверенностью, что они понимают) приблизительно за 10 минут, это слишком сложно.
Наряду с огромными выражениями, существуют основные ограничения на слова, которые могут быть обработаны regexp. Например, Вы не можете не записать regexp для слова, описанного n символами a, затем n символы b, где n может быть любым, более строго .
На различных языках regexp является расширением Регулярный язык , но время парсинга может быть чрезвычайно большим, и этот код является непортативным.
Проблема слишком сложна для регулярных выражений, когда ограничения проблемы могут измениться после того, как решение записано. Так, в Вашем примере, как можно быть уверены, адрес электронной почты допустим, когда у Вас нет доступа к целевой почтовой системе, чтобы проверить, что адрес электронной почты присоединен к действительному пользователю? Вы не можете.
Каждый раз, когда Вы не можете быть уверены, что это действительно решает проблему, например:
Особенно поэтому, когда там уже существуют инструменты, которые решают проблему полностью понятным способом.
Regex может использоваться в доменах, которые я упомянул, но только как подмножество целой проблемы и для определенных, простых случаев.
Это идет вне технических ограничений regexes (регулярные языки + расширения), предел пригодности для обслуживания и удобочитаемости превзойден намного ранее, чем технический предел в большинстве случаев.
Это может звучать глупым, но я часто оплакиваю неспособность сделать тип БД запросов с помощью регулярного выражения. Теперь особенно больше затем прежде, потому что я ввожу те типы строки поиска все время на поисковых системах. его очень трудное, если не невозможный искать +complex AND +"regular expression"
, Например, как я ищу в emacs команды, которые имеют и Буфер и Окно на их имя? Я должен искать отдельно .*Buffer.*Window and .*Window.*Buffer
Мой предел является шаблоном Regex, это - приблизительно 30-50 символов в длину (варьирующийся в зависимости от того, сколько фиксированный текст и сколько команды regex)