Получил простую задачу, чтобы получить выражение XPath и вернуть префикс, соответствующий родительскому элементу узла, который (может быть) выбран.
Пример:
/aaa/bbb => /aaa
/aaa/bbb/ccc => /aaa/bbb
/aaa/bbb/ccc[@x='1' and @y="/aaa[name='z']"] => /aaa/bbb
Поскольку шаблоны внутри квадратных скобок могут содержать скобки в кавычках, я решил попытаться добиться этого с помощью регулярных выражений. Вот фрагмент кода:
string input =
"/aaa/bbb/ccc[@x='1' and @y=\"/aaa[name='z'] \"]";
// ^-- remove space for no loop
string pattern = @"/[a-zA-Z0-9]+(\[([^]]*(]"")?)+])?$";
System.Text.RegularExpressions.Regex re =
new System.Text.RegularExpressions.Regex(pattern);
bool ismatch = re.IsMatch(input); // <== Infinite loop in here
// some code based on the match
Поскольку шаблоны довольно регулярны, я искал '/', за которым следовал идентификатор, за которым следовала необязательная группа, совпадающая в конце строки (....)?$
Код, казалось, работал, но играя с разными значениями для входной строки, я обнаружил, что, просто вставив пробел (в место, показанное в комментарии), функция .NET IsMatch входит в бесконечный цикл, забирая все ресурсы ЦП. .
Теперь, независимо от того, является ли этот шаблон регулярного выражения лучшим (у меня был более сложный, но упрощенный, чтобы показать проблему), это, похоже, показывает, что использование RegEx с чем-то нетривиальным может быть очень рискованным.
Я что-то упускаю? Есть ли способ защититься от бесконечных циклов при совпадении регулярных выражений?