Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/233.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 通过正则表达式提取样式表_Php_Regex - Fatal编程技术网

Php 通过正则表达式提取样式表

Php 通过正则表达式提取样式表,php,regex,Php,Regex,是的,我知道,我知道,用正则表达式解析HTML非常糟糕。但我使用的是遗留代码,它应该从html页面中提取所有链接和样式元素。我会更改它并使用dom扩展名,但是在正则表达式之后,有一个巨大的代码块,它依赖于preg\u match\u all返回匹配结果的方式 脚本正在使用以下正则表达式: $pattern = '/<(link|style)(?=.+?(?:type="(text\/css)"|>))(?=.+?(?:media="(.*?)"|>))(?=.+?(?:href

是的,我知道,我知道,用正则表达式解析HTML非常糟糕。但我使用的是遗留代码,它应该从html页面中提取所有
链接
样式
元素。我会更改它并使用
dom
扩展名,但是在正则表达式之后,有一个巨大的代码块,它依赖于
preg\u match\u all
返回匹配结果的方式

脚本正在使用以下正则表达式:

$pattern = '/<(link|style)(?=.+?(?:type="(text\/css)"|>))(?=.+?(?:media="(.*?)"|>))(?=.+?(?:href="(.*?)"|>))(?=.+?(?:rel="(.*?)"|>))[^>]+?\2[^>]+?(?:\/>|<\/style>)\s*/is';

preg_match_all($pattern, $htmlContent, $cssTags);
$pattern='/)(?=.+?(?:media=“(.*?”))(?=.+?(?:href=“(.*?”))(?=.+?(?:rel=“(.*?”))[^>]+?\2[^>]+(?:\/>)\s*/is';
preg_match_all($pattern、$htmlContent、$cssTags);

但它不起作用。没有匹配的元素。不幸的是,我在正则表达式方面真的很差劲,所以如果有人能帮助我,那就太好了。

我会把这个问题分解成几个小问题。它将更容易编写,更容易维护。当然还有更多的代码行。一个大型正则表达式的问题是存在许多gotcha,输入可能无效,这在一个大型模式中很难管理

/<link([^>]+)>/
-> extract attributes:
   /([\w]+)\s*=\s*"([^"]*)"/

/<style[^>]*>(.+?)</style>/
-> extract inline styles
/]+)>/
->提取属性:
/([\w]+)\s*=\s*”([^“]*)”/
/]*>(.+?)/
->提取内联样式

最后将结果合并到一个数组中,就好像preg_match_都生成了它一样。

如果我使用正则表达式来实现这一点,例如,因为您需要能够处理无效的HTML,而使用适当的解析器往往很难处理无效的HTML,我会使用单独的正则表达式。使用一个或两个正则表达式来获得
样式和
链接ode>标记,并使用另一组正则表达式从每个标记获取各种属性

您的正则表达式试图通过使用lookahead重复扫描开始标记以获取所有元素,从而一次完成所有操作。在一个正则表达式是您可以使用的全部的情况下,这是一个巧妙的技巧,但在编写您自己的代码时不推荐使用它

我对你的正则表达式做了一些改进。为了提高效率,我在可能的情况下用否定的字符类替换了
*?
+?
。你的正则表达式不起作用的原因是它没有正确地尝试匹配结束标记,也没有正确地处理没有结束标记的
链接
标记。我解决了这个问题

正则表达式:

<(link|style)(?=[^<>]*?(?:type="(text/css)"|>))(?=[^<>]*?(?:media="([^<>"]*)"|>))(?=[^<>]*?(?:href="(.*?)"|>))(?=[^<>]*(?:rel="([^<>"]*)"|>))(?:.*?</\1>|[^<>]*>)
)(?=[^]*?(?:media=“([^”]*)”|>)(?=[^]*?(?:href=“(.*?)”|>)(?=[^]*(?:rel=“([^”]*)”|>)(?:*。[^]*>)
PHP:

$pattern='%)(?=[^]*?(?:media=“([^”]*)”|>)(?=[^]*?(?:href=“(.*?)”|>)(?=[^]*(?:rel=“([^”]*)”|>)(?:。。。[^]*>)%si

非常感谢您的回答,但我最终使用DOM扩展重写了这一部分。这将使它更加健壮。

仅获取外部资源:

preg_match_all('#(<link\s(?:[^>]*rel="stylesheet")[^>]*>)\R?#is', $content, $matches, PREG_SET_ORDER)
preg#u match_all('#(]*rel=“stylesheet”)[^>]*>)\R?#is',$content,$matches,preg#u SET_ORDER)

所有匹配项都被使用了?我是指类型、媒体等?@galambalazs是的,就我所见,情况就是这样。巨大的代码块听起来是重构的一个很好的候选者。扔掉它以获得合适的DOM解决方案。如果需要,您可以从DOM库中获取结果,并从preg中创建与匹配项数组相同的数组结构_全部匹配
preg_match_all('#(<link\s(?:[^>]*rel="stylesheet")[^>]*>)\R?#is', $content, $matches, PREG_SET_ORDER)