Если бы я делал это с помощью регулярных выражений, например, потому что вам нужно иметь возможность обрабатывать недопустимый HTML, который часто затруднен при правильном парсере, я бы использовал отдельные регулярные выражения.Используйте одно или два регулярных выражения, чтобы получить теги style
и link
, и используйте другой набор регулярных выражений, чтобы получить различные атрибуты от каждого тега.
Ваше регулярное выражение пытается сделать все сразу, используясканируйте открывающий тег несколько раз, чтобы получить все элементы.Это хитрый трюк в ситуации, когда вы можете использовать только одно регулярное выражение, но не то, что рекомендуется при написании собственного кода.
Я внес некоторые улучшения в ваше регулярное выражение.Я заменил .*?
и .+?
на отрицательные классы символов, где это было возможно для эффективности.Причина, по которой ваше регулярное выражение не сработало, заключается в том, что он неправильно пытается сопоставить закрывающий тег или неправильно обрабатывает теги link
, у которых нет закрывающего тега.Я исправил это.
Регулярное выражение:
<(link|style)(?=[^<>]*?(?:type="(text/css)"|>))(?=[^<>]*?(?:media="([^<>"]*)"|>))(?=[^<>]*?(?:href="(.*?)"|>))(?=[^<>]*(?:rel="([^<>"]*)"|>))(?:.*?</\1>|[^<>]*>)
PHP:
$pattern = '%<(link|style)(?=[^<>]*?(?:type="(text/css)"|>))(?=[^<>]*?(?:media="([^<>"]*)"|>))(?=[^<>]*?(?:href="(.*?)"|>))(?=[^<>]*(?:rel="([^<>"]*)"|>))(?:.*?</\1>|[^<>]*>)%si'