2010-06-30 3 views
1

예, 알고 있습니다. 정규 표현식으로 HTML을 구문 분석하는 것은 매우 나쁩니다. 하지만 html 페이지에서 모든 linkstyle 요소를 추출해야하는 기존 코드로 작업하고 있습니다. 내가 그것을 변경하고 대신 dom 확장을 사용하지만, 정규 표현식 후에는 preg_match_all이 일치하는 결과를 반환하는 거대한 코드 블록이 있습니다.정규식을 통한 스타일 시트 추출

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

preg_match_all($pattern, $htmlContent, $cssTags); 

를하지만 작품을 나던 :

스크립트는이 정규식을 사용하고 있습니다. 일치하는 요소가 없습니다. 불행히도 나는 정규식을 정말 빨아 먹는다. 누군가 나를 도울 수 있다면 좋을 것이다.

+0

모든 일치가 사용됩니다 – galambalazs

+0

@galambalazs 네, 제가 알기로는 이것이 사실입니다. – Max

+0

* 거대한 코드 블록 *은 리팩토링을위한 좋은 후보자처럼 들립니다. 적절한 DOM 솔루션을 위해 그것을 버리십시오. – Gordon

답변

0

귀하의 답변에 모두 감사합니다,하지만 난 마침내 DOM 확장을 사용하여 해당 비트를 다시 썼다. 그렇게하면 더 강력해질 것입니다.

preg_match_all('#(<link\s(?:[^>]*rel="stylesheet")[^>]*>)\R?#is', $content, $matches, PREG_SET_ORDER) 
1

이 문제는 몇 가지 작은 문제로 해결할 것입니다. 글을 쓰는 것이 더 쉬우 며, 유지하기가 더 쉬울 것입니다. 그리고 물론 코드의 라인을 조금 더. 하나의 거대한 정규식의 문제점은 몇 가지 문제가 있으며 입력이 무효가 될 수 있다는 것입니다.이 입력은 하나의 큰 패턴으로 관리하기가 어렵습니다.

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

/<style[^>]*>(.+?)</style>/ 
-> extract inline styles 

마지막으로 preg_match_all이 생성 한 것처럼 결과를 배열에 병합합니다.

0

정규식으로이를 수행하는 경우 (예 : 적절한 구문 분석기로는 종종 어려운 HTML을 처리 할 수 ​​있어야하기 때문에 별도의 정규 표현식을 사용합니다. 하나 또는 두 개의 정규식을 사용하여 stylelink 태그를 가져오고 다른 태그 집합에서 다양한 속성을 가져 오려면 다른 정규식 세트를 사용하십시오.

당신의 regex는 lookahead를 사용하여 모든 요소를 ​​얻기 위해 반복적으로 여는 태그를 스캔하여 모든 것을 시도합니다. 그것은 하나의 정규식을 사용할 수있는 모든 것이지만 자신의 코드를 작성할 때 권장할만한 것이 아닌 상황에서 깔끔한 트릭입니다.

나는 당신의 정규 표현식을 약간 개선했다. 가능한 경우 효율성을 위해 .*?.+?을 부정 문자 클래스로 바꿨습니다. 정규식이 작동하지 않는 이유는 닫는 태그와 정확히 일치하지 않거나 닫는 태그가없는 link 태그를 올바르게 처리하지 못하기 때문입니다. 나는 그것을 고쳤다.

정규식 :

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

PHP :

$pattern = '%<(link|style)(?=[^<>]*?(?:type="(text/css)"|>))(?=[^<>]*?(?:media="([^<>"]*)"|>))(?=[^<>]*?(?:href="(.*?)"|>))(?=[^<>]*(?:rel="([^<>"]*)"|>))(?:.*?</\1>|[^<>]*>)%si' 
0

는 단지 외부 리소스 잡아하려면? 유형, 미디어 등을 의미합니까?