代码之家  ›  专栏  ›  技术社区  ›  Alex

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

  •  1
  • Alex  · 技术社区  · 15 年前

    我有一个HTML文档,我想在其中自动添加一个版本号到所有脚本和样式表引用。

    应更换以下部件

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

    用那个

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

    其中123456是我的动态版本号。

    但应该只在本地文件上做

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

    应该保持原样。

    到目前为止,我有以下regex:

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

    但这并不是百分之百有效的,我相信有更好的方法可以做到这一点。 你会怎么写?

    编辑:

    我现在用的是domdocument,但结果发现它相当慢!

        <?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 回复  |  直到 15 年前
        1
  •  2
  •   Gumbo    15 年前

    您最好使用类似于 Simple HTML DOM Parser DOMDocument 找到元素/属性。然后可以使用正则表达式修改属性值。

    下面是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
  •  3
  •   Luca Matteis    15 年前

    不要使用regex,至少不要找到 src 价值观。使用DOM。

    var allScriptTags = document.getElementsByTagName("script");
    var allLinkTags = document.getElementsByTagName("link");
    
    for(var i=0; i<allScriptTags.length; i++) {
        var srcAttribute = allScriptTags[i].getAttribute("src");
    
        // ... do something with srcAttribute ...
    
        // replace it with the modified value
        allScriptTags[i].setAttribute("src", srcAttribute);
    }
    
        3
  •  1
  •   Mike Anchor    15 年前

    为什么不做一些更简单的事情,比如:

    $version = 12345;
    function print_local_css($base_filename)
    {
        global $version;
        print '<link rel="stylesheet" type="text/css" href="'.$base_filename.'.v'.$version.'.css" />';
    }
    
    function print_local_js($base_filename)
    {
        global $version;
        print '<script type="text/javascript" src="'.$base_filename.'.v'.$version.'.js"></script>';
    }
    

    它会很快,一个位置来更改版本和任何你不想被版本控制的文件,只需手动放入HTML。