Regex для добавления номера версии к ссылкам .js и .css в документе HTML - PullRequest
1 голос
/ 11 февраля 2010

У меня есть 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" />

следует оставить нетронутым.

Пока у меня есть следующее регулярное выражение:

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

Но это не работает на 100%, и я уверен, что есть лучший способ сделать это. Как бы вы это написали?

Edit:

У меня сейчас есть 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 ]

3 голосов
/ 11 февраля 2010

Не используйте регулярные выражения, по крайней мере, чтобы не найти значения 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);
}
2 голосов
/ 11 февраля 2010

Вам лучше использовать HTML-анализатор, например Простой HTML-анализатор DOM или 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);
    }
}
1 голос
/ 11 февраля 2010

почему бы не что-то более простое, как:

$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 вручную.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...