PCRE (php) регулярное выражение, подшаблон с + соответствует, а с * нет? - PullRequest
0 голосов
/ 31 января 2011

Я хочу сопоставить и перехватить все существующие (если есть) блоки <style...</style> и внутри одного блока <body..</body> внутри HTML-документа.Я думал, что это было просто, но я столкнулся с чем-то странным.Это было мое предположение для всего регулярного выражения:

/(<style[\s\S]+<\/style>)*[\s\S]*<body.*>([\s\S]+)<\/body>/i

Это ни к чему не приводит.Так что я разбил его на части, и эти части работают:

/(<body.*>([\s\S]+)<\/body>)/i
/(<style[\s\S]+<\/style>)/i

И самая странная из всех этих первых строк тоже работает, в то время как вторые результаты пустые!

/(<style[\s\S]+<\/style>)+/i
/(<style[\s\S]+<\/style>)*/i

Итак, я предполагаю ошибкуразница между * и + после подшаблона.Зачем?И как мне это решить?

Спасибо !!

1 Ответ

1 голос
/ 31 января 2011

У вас есть четыре проблемы:

Во-первых, вы используете регулярные выражения для разбора HTML.

В-третьих, вы слишком много подходите: вам нужно хотя бы сделать некоторые квантификаторы ленивыми, т.е. е. используйте .*?, [\s\S]*? и т. д., или ваше регулярное выражение будет сопоставлять все до конца строки или файла, а затем только откатить назад столько, сколько необходимо, чтобы найти последний возможный соответствующий тег.

В-четвертых, вы настроили себя на катастрофическое возвращение назад, имея повторяющиеся группы внутри повторяющихся групп, каждая из которых имеет множество способов сопоставления одного и того же текста.

Как я понимаю ваш вопрос, вы хотите сопоставить все, начиная от первого тега <style> и заканчивая конечным </body>, и захватить все содержимое тегов <style> и содержимое тега <body>. Правильно? Тогда попробуйте

/(<style[\s\S]+<\/style>)[\s\S]*?<body.*?>([\s\S]+)<\/body>/i

Чтобы захватить каждый блок <style> по отдельности, можно попробовать максимум четыре <style> блока:

/(<style[\s\S]+?<\/style>)?\s*(<style[\s\S]+?<\/style>)?\s*(<style[\s\S]+?<\/style>)?\s*(<style[\s\S]+?<\/style>)?\s*<body.*?>([\s\S]+)<\/body>/i

, если блоки <style> все смежные и разделены только пробелами. Вы понимаете, почему не рекомендуется использовать для этого регулярное выражение?

...