Попробуйте это:
'(?><TABLE>\n+(?:(?!</TABLE>|NAME=).*\n+)*)NAME="([^"]+)"'
(?:.*\n+)*
использует все ненужные строки, в то время как встроенный упреждения - (?!</TABLE>|NAME=)
- предотвращает выход за пределы первого поля NAME или конца записи TABLE.,На всякий случай, если есть запись без поля NAME, я обернул большую часть выражения в атомарную группу - (?>...)
- для предотвращения бессмысленного возврата.
Обратите внимание, что сейчас существует только одна группа захвата.Полезно использовать их только тогда, когда вам действительно нужно что-то запечатлеть;в противном случае используйте не захватывающий вариант: (?:...)
.
РЕДАКТИРОВАТЬ: почему ваше регулярное выражение не работает, короткий ответ жадность.После сопоставления с открывающим тэгом эта часть вступает во владение:
((NAME="(.+)")|(.*|\n))*
Часть в самых внешних паренах может соответствовать чему угодно: тегам, NAME=
строкам, переводам строк - даже пустым строкам.Оберните это в группу, контролируемую жадным *
, и теперь оно соответствует всему .Там нет ничего, что могло бы остановить совпадение в первом поле ИМЯ или даже в конце записи.
Таким образом, он на самом деле "находит" каждое вхождение NAME="..."
строк, но делает это в одной попытке сопоставления, которая потребляет весь ввод сразу.На каждой итерации включающей *
группы захвата перезаписываются;когда это будет сделано, окончательное значение ИМЯ - MyName IsKhan
- это то, что осталось в группе 4.
Я использовал отрицательный взгляд, чтобы проверить жадность, но вы также можете сделать это более напрямую,с помощью нежадного квантификатора.Вот как бы выглядело мое регулярное выражение с неохотным *
вместо отрицательного взгляда:
'<TABLE>\n+(?:.*\n+)*?NAME="([^"]+)"'
Простой переход на не жадный квантификатор не помог бы с вашим регулярным выражением;вам также придется внести некоторые структурные изменения.