dselp3944 2010-02-11 11:06
浏览 109
已采纳

正则表达式,用于在HTML文档中为.js和.css引用添加版本号

I have a HTML document where I want to automatically have a version number added to all script and style sheet references.

the following should be replaced

 <link ... href="file.css" media="all" />
 <script ... src="file.js"></script>
 <script ... src="http://myhost.com/file.js"></script>

with that

<link ... href="file.v123456.css" media="all" />
<script ... src="file.v123456.js"></script>
<script ... src="http://myhost.com/file.v123456.js"></script>

where 123456 is my dynamic version number.

But it shoud ONLY do that on local files

<link ... href="http://otherhost.com/file.css" media="all" />

should be left untouched.

So far I have the following regex:

$html = preg_replace('#(src|href)=("|\')(?!http)(?!("|\'| |\+))(.*)\.(css|js|swf)("|\')#Ui', '\\1=\\2\\3\\4.v'.$version .'.\\5\\6', $html);

But it does not work 100% and I am sure that there is a better way in doing this. How would you write it?

Edit:

I have it now using DOMDocument, but it turns out that it's pretty slow!

    <?php
//------- snip --------------
            $host       = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'];
            $refs       = array();
            $version    = "v". $version;
            $doc        = new DOMDocument();        
            $tmpDoc     = $html;

            $doc->loadHTML($tmpDoc);        
            $xpath = new DOMXPath($doc);
            foreach($xpath->query('/html/head/link/@href') as $href) {
                $ref = $href->value;
                if(
                    !preg_match('/^https?:/', $ref) || 
                    strpos($ref, $host) === 0               
                ) {
                    $refs[$ref] = preg_replace('/\.css$/', '.'.$version.'$0', $ref);
                }
            }
            foreach ($xpath->query('//script/@src') as $src) {
                $ref = $src->value;
                if(
                    !preg_match('/^https?:/', $ref) ||
                    strpos($ref, $host) === 0
                ) {
                    $refs[$ref] = preg_replace('/\.js$/', '.'.$version.'$0', $ref);
                }
            }       
            $html = str_replace(
                        array_keys($refs), 
                        array_values($refs), 
                        $tmpDoc
                    );
//------- snip --------------
    ?>
  • 写回答

3条回答 默认 最新

  • duanlinpi0265 2010-02-11 11:30
    关注

    You should better use a HTML parser like Simple HTML DOM Parser or DOMDocument to find the elements/attributes. Then you can use regular expressions to modify the attribute values.

    Here’s an example for DOMDocument:

    $version = 'v123456';
    $doc = new DOMDocument();
    $doc->loadHTML($code);
    $xpath = new DOMXPath($doc);
    foreach ($xpath->query('/html/head/link/@href') as $href) {
        if (!preg_match('/^https?:/', $href->value)) {
            $href->value = preg_replace('/\.css$/', '.'.$version.'$0', $href->value);
        }
    }
    foreach ($xpath->query('//script/@src') as $src) {
        if (!preg_match('/^https?:/', $src->value)) {
            $src->value = preg_replace('/\.js$/', '.'.$version.'$0', $src->value);
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥50 切换TabTip键盘的输入法
  • ¥15 可否在不同线程中调用封装数据库操作的类
  • ¥15 微带串馈天线阵列每个阵元宽度计算
  • ¥15 keil的map文件中Image component sizes各项意思
  • ¥20 求个正点原子stm32f407开发版的贪吃蛇游戏
  • ¥15 划分vlan后,链路不通了?
  • ¥20 求各位懂行的人,注册表能不能看到usb使用得具体信息,干了什么,传输了什么数据
  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 Centos / PETGEM
  • ¥15 划分vlan后不通了