Многие объяснения уже присутствуют, чтобы объяснить, как это происходит и как это исправить, но вы также должны следовать рекомендациям, чтобы избежать NullPointerException
вообще.
См. также: A хороший список лучших практик
Я бы добавил, очень важно, хорошо использовать модификатор final
. Использование "окончательной" модификатор, когда это применимо в Java
Сводка:
final
для обеспечения хорошей инициализации. @NotNull
и @Nullable
if("knownObject".equals(unknownObject)
valueOf()
поверх toString (). StringUtils
StringUtils.isEmpty(null)
. Нет. Это - это легкое. Конечный автомат (который является структурой данных, лежащей в основе регулярного выражения) не имеет памяти кроме состояния, это находится в, и если у Вас есть произвольно глубокое вложение, Вам нужен произвольно большой автомат, который сталкивается с понятием конечный автомат.
можно соответствовать, вложил/соединил элементы до фиксированной глубины, где глубина только ограничена памятью, потому что автомат становится очень большим. На практике, однако, необходимо использовать автомат с магазинной памятью, т.е. синтаксический анализатор для контекстно-свободной грамматики, например, LL (сверху вниз) или LR (вверх дном). Необходимо принять худшее поведение во время выполнения во внимание: O (n^3) по сравнению с O (n), с n = длина (вводится).
существует много avialable парсеров-генераторов, например ANTLR для Java. Нахождение существующей грамматики для Java (или C) является также не трудным.
Для большего количества фона: Теория автоматов в Википедии
Вероятно, рабочее решение для Perl, если строка находится на одной строке:
my $NesteD ;
$NesteD = qr/ \{( [^{}] | (??{ $NesteD }) )* \} /x ;
if ( $Stringy =~ m/\b( \w+$NesteD )/x ) {
print "Found: $1\n" ;
}
РЕДАКТИРОВАНИЕ HTH
: проверка:
И еще одна вещь Torsten Marek (кто указал правильно, что это больше не regex):
Да, если это - RegEx-механизм.NET. механизм.Net поддерживает конечный автомат, предоставленный внешним стеком. см. детали
Насосная лемма для регулярных языков является причиной, почему Вы не можете сделать этого.
сгенерированный автомат будет иметь конечное число состояний, скажет k, таким образом, строка фигурных скобок открытия k+1 будет обязана иметь состояние, повторенное где-нибудь (поскольку автомат обрабатывает символы). Часть строки между тем же состоянием может дублироваться бесконечно много раз, и автомат не будет знать различия.
, В частности, если это принимает фигурные скобки открытия k+1, сопровождаемые k+1 закрывающими фигурными скобками (который это должно) это также примет накачанное количество открытия фигурных скобок, сопровождаемых неизменными припоями закрытия k+1 (который это не было должно).
Надлежащие Регулярные выражения не были бы в состоянии сделать это, поскольку Вы оставите область Регулярных языков для приземления в территориях Бесконтекстных языков.
, Тем не менее, пакеты "регулярного выражения", которые предлагают много языков, строго более мощны.
, Например, Lua регулярные выражения имеют" %b()
" устройство распознавания, которое будет соответствовать сбалансированной круглой скобке. В Вашем случае Вы использовали бы" %b{}
"
, Другой сложный инструмент, подобный sed, gema, где Вы будете соответствовать сбалансированным фигурным скобкам очень легко {#}
.
Так, в зависимости от инструментов у Вас есть в Вашем распоряжении свое "регулярное выражение" (в более широком смысле), может быть в состоянии соответствовать вложенной круглой скобке.
как zsolt упомянутый, некоторые regex механизмы поддерживают рекурсию - конечно, они обычно - те, которые используют алгоритм отслеживания в обратном порядке, таким образом, это не будет особенно эффективно. пример: /(?>[^{}]*){(?>[^{}]*)(?R)*(?>[^{}]*)}/sm
Нет, Вы входите в область Контекстно-свободные грамматики в той точке.
Кажется, работает: / (\ {(?: \ {. * \} | [^ \ {]) * \}) / m