Хорошо, тогда давайте разберемся с этим:
Input: /aaa/bbb/ccc[@x='1' and @y="/aaa[name='z'] "]
Pattern: /[a-zA-Z0-9]+(\[([^]]*(]")?)+])?$
(я полагаю, вы имели в виду \ "в вашей C # -экранированной строке, а не" "... перевод из VB.NET?)
Сначала / [a-zA-Z0-9] + сожрет первую квадратную скобку, оставив:
Input: [@x='1' and @y="/aaa[name='z'] "]
Внешняя группа (\ [([^]] * (] "")?) +])? $ "Должна совпадать, если перед EOL есть 0 или 1 экземпляр. Так что давайте разберемся внутри и посмотрим, если это соответствует чему угодно.
"[" сразу же сожрет, оставив нам:
Input: @x='1' and @y="/aaa[name='z'] "]
Pattern: ([^]]*(]")?)+]
Разбивка шаблона: сопоставьте 0 или более не ] символов, а затем сопоставьте "] 0 или 1 раз и продолжайте делать это, пока не сможете. Затем попробуйте найти и проглотить ] потом.
Шаблон соответствует на основе [^]] *, пока не достигнет ] .
Поскольку между ] и " есть пробел, он не может сожрать ни одного из этих символов, но ? после (]" ) позволяет в любом случае вернуть true.
Теперь мы успешно сопоставили ([^]] * (] ")?) один раз, но + говорит, что мы должны пытаться сопоставлять его любое количество раз мы можем.
Это оставляет нас с:
Input: ] "]
Проблема здесь в том, что этот вход может совпадать с ([^]] * (] ")?) * бесконечное число раз без сожжения и" + " заставит его просто продолжать пытаться.
Вы по существу соответствуете «1 или более» ситуаций, в которых вы можете сопоставить «0 или 1» чего-то, за которым следует «0 или 1» чего-то другого. Так как ни один из двух подшаблонов не существует в оставшемся входе, он продолжает соответствовать 0 из [^]] \ * и 0 из (] ")? в бесконечном цикле.
Ввод никогда не сожрается, а оставшаяся часть шаблона после «+» никогда не оценивается.
(Надеюсь, я получил SO-escape-of-regex-escape прямо выше.)