【问题标题】:Regular expression for CSS class namesCSS 类名的正则表达式
【发布时间】:2015-03-14 19:59:07
【问题描述】:

我正在尝试在 PHP 中创建一个函数,该函数将遍历 CSS 和 JS 文件,并在 CSS 选择器中替换类名和 ID(但不是直接的 HTML 元素或其中的 CSS 属性),而不会破坏其他内容。然而,在世界上所有的愚蠢运气中,我对正则表达式毫无希望。

我有两个数组,一个包含“原始”单词,一个包含我想要转换成的单词。

$array1 = array("ul", "text", "border");
$array2 = array("bar", "foo", "far");

$str = magic($str, $array1, $array2);

而这个神奇的功能会改变下面的 CSS 文件

#test-text ul {
    text-decoration: none;
}
.ul-border span {
    border: 1px solid #fff;
}
#text.niceborder {
    border-color: #ccc;
}

进入

#test-foo ul {
    text-decoration: none;
}
.bar-far span {
    border: 1px solid #fff;
}
#foo.nicefar {
    border-color: #ccc;
}

我希望同样的函数可以用于 JS 中的 jQuery 选择器做同样的事情,但是如果我得到了找到合适的选择器的基本逻辑并且只为 .和 # 个片段,我想我可以自己制作一个 $() 改编;)

谢谢你

【问题讨论】:

  • 这个 CSS 必须很大,这样才能更容易地编写工具,而不仅仅是一个一个替换类。
  • 你的意思是我应该手动替换类名? $array2 的内容取决于用户输入,所以我需要动态更改类名。
  • 这个数组中有多少项?多次运行 preg_replace 可以吗?
  • 您要解决的问题是什么?您可以为您的 css 文件使用模板吗?
  • 转换繁重也没关系,因为结果文件被缓存了。因此,无论需要多少 preg_replaces,都可以

标签: php css regex


【解决方案1】:

我不知道你为什么需要它,但我认为这是你想要的功能:

<?php

/**
 * Replaces all occurences in a CSS class or ID name with the provided replacement.
 * 
 * @param string $subject
 * @param array $search
 * @param array $replace
 * @return string 
 */
function replaceNames($subject, $search, $replace)
{
    // First generate all search regular expressions
    $searchRegexpressions = array_map(function($s)
    {
        return '/([\#\.][a-z0-9\-_]*)(' . preg_quote($s) . ')/i';
    }, $search);
    // Now all associated replacement expressions
    $replaceRegexpressions = array_map(function($r)
    {
        return '$1' . $r;
    }, $replace);

    do {
        // Now do the replacements as often as necessary to replace every occurence.
        $subject = preg_replace($searchRegexpressions, $replaceRegexpressions, $subject, -1, $count);
    } while ($count > 0);

    return $subject;
}
?>

解释正则表达式:

/([\#\.][a-z0-9\-_]*)(' . preg_quote($s) . ')/i
  1. 必须以 # 或 . 开头。
  2. 字母、数字或 - _ 可以随心所欲地跟随 (*)。 (如果你有更时髦的类名,你可能需要添加字符。)
  3. 有问题的字符串。

另外:我使用了匿名函数。如果您不使用 PHP 5.3.0+,则必须实际创建两个映射函数,并改用:array_map(mySearchRegexFuncion, $search);

【讨论】:

  • 太棒了!就像我想要的魔法一样工作,非常感谢! :)
  • 我开始将项目添加到数组中,一切都很顺利,直到我达到数组中的第 61 个值,此时函数开始输出空白(值 1-60 仍然可以正常转换)。是代码有问题还是我的配置有问题?我不得不单独移动这些函数,因为我运行的是 PHP 5.2.8
  • Mh.. PHP 可能存在字符串大小问题。您是否从文件中获取字符串?在这种情况下,您可以逐行执行。
  • 有道理,因为该文件大约有 3500 行...好吧,我将逐行处理。谢谢你的一切!
【解决方案2】:

我很难找到一个理由,你正在尝试做的事情永远是一个好主意。如果您只想根据某些设置或基于 PHP 的逻辑更改一堆样式,只需使用 PHP 生成一个类名,然后可以使用它来生成覆盖 CSS 规则。

像这样:

<?php
  $a = "my-a-style";
  $b = "my-b-style";
  $parentClass = someLogicalFunction() ? $a : $b;
?>
<div class="<?php echo $parentClass; ?>">
  <div id="test">
    <ul>
      <li><span>Some Stuff</span></li>
    </ul>
  </div>
</div>

现在您可以创建单独的 CSS 规则:

.my-a-style #test {}
.my-b-style #test {}

【讨论】:

  • 这对于我最初的问题来说是一个很好的解决方案。但是,出于性能原因,我也期待使用相同的代码来混淆和缩短我的类名。所以 .main-general-float-wrapper-spacer 变成 .m-g-f-w-s
  • @Emphram:你为什么曾经有这么长的类名? .main-general-float-wrapper-spacer 太荒谬了。你意识到你可以在一个元素上拥有多个类,对吧?
  • 可以,但如果你想支持IE6就不行。
  • IE6 DOES 支持多类,只是不支持多类选择。
猜你喜欢
  • 2011-09-13
  • 2016-09-26
  • 1970-01-01
  • 2019-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多