由LESS replace()函数行为困惑

时间:2014-11-24 16:45:52

标签: css regex less

我试图编写一个LESS mixin,它使用字符串的一部分来形成一个类名。我希望能够使用replace()为变量提供值,然后在规则中使用该变量。这是我写的测试,以验证它是否有效:

.foo(@xyz) {
  @pfx: replace(@xyz, "(.).*", "$1");

  .@{pfx}-foo { margin: 0; }
}

.foo(abcdefghijklmnop);

当我通过lessc(1.7.4)(编辑 - 也是2.1.0)运行时, kind-of 有效,生成:

.aaa-foo {
  margin: 0;
}

因此,replace()正确地从我传入的字符串中提取第一个字符(" a"),而不是

.a-foo

它给了我

.aaa-foo

我查看了replace()功能的来源,这很简单,所以我对发生的事情完全感到困惑。 (我已经尝试将正则表达式设为"^(.).*$",结果相同。)

我稍微扩展了测试:

.foo(@xyz) {
  @pfx: replace(@xyz, "(.).*", "$1");

  .@{pfx}-foo { margin: 0; content: "@{pfx}"; }
}

.foo(abcdefghijklmnop);

给了我:

.aaa-foo {
  margin: 0;
  content: "a";
}

这意味着正则表达式工作正常。

3 个答案:

答案 0 :(得分:2)

试试这个

.foo(@xyz) {
  @props: ~`"@{arguments}"`;

  @pfx: replace(@props, "^(.).*$", "$1");

  .@{pfx}-foo { margin: 0; }
}

.foo(abcdefghijklmnop);

修改

同样回答评论,你想传递一个字符串来替换,实际上一个更简单的版本就是使用.foo(~"abcdefghijklmnop")强制较少将参数视为字符串而不输出引号。

答案 1 :(得分:2)

试试这个:

@pfx: e(replace(@xyz, "^(.).*$", "$1"));

或者这个:

@pfx: replace(~"@{xyz}", "^(.).*$", "$1");

请参阅e功能的文档。

答案 2 :(得分:2)

显然提供了一些解决方法,但它的工作方式仍然是一个神话。

评估后的AST完全正确,如下所示:

Element { combinator: { value: '', emptyOrWhitespace: true },
  value: '.',
  index: 54,
  currentFileInfo: 
   { filename: 'input',
     relativeUrls: undefined,
     rootpath: '',
     currentDirectory: '',
     entryPath: '',
     rootFilename: 'input' } },
Element { combinator: { value: '', emptyOrWhitespace: true },
  value: 
   Quoted { escaped: undefined,
     value: 'a',
     quote: 'a',
     index: undefined,
     currentFileInfo: undefined },
  index: 55,
  currentFileInfo: 
   { filename: 'input',
     relativeUrls: undefined,
     rootpath: '',
     currentDirectory: '',
     entryPath: '',
     rootFilename: 'input' } },
Element { combinator: { value: '', emptyOrWhitespace: true },
  value: '-foo',
  index: 61,
  currentFileInfo: 
   { filename: 'input',
     relativeUrls: undefined,
     rootpath: '',
     currentDirectory: '',
     entryPath: '',
     rootFilename: 'input' } }

但是当生成CSS代码时,事情会很快发生。

Quoted.prototype.genCSS = function (context, output) {
    if (!this.escaped) {
        output.add(this.quote, this.currentFileInfo, this.index);
    }
    output.add(this.value);
    if (!this.escaped) {
        output.add(this.quote);
    }
};

Quoted节点将在未转义时输出带有引号的值。然而,不知何故,引用是值的第一个字符,在这种情况下说'a'

e()周围应用replace时,较少会将Anonymous节点放在AST而不是Quoted节点中,因此不会输出引号。