细分字符串和返回对象

问题描述 投票:0回答:1

我正在研究一种工具而且卡住了。

我正在访问网站的样式表对象,只想获得“CSSFontFaceRule”。我解决了这个问题,但我返回的对象中的输出是一个巨大的字符串。我想将字符串细分为on对象。我还创造了一个小提琴:http://jsfiddle.net/9eoytc6v/1/

这是我的现状:

@font-face {font-family: "Test-Book";
src: 
    url("https://fontserver.xyz/test.eot?#iefix") format("embedded-opentype"),
    url("https://fontserver.xyz/test.woff2") format("woff2"),
    url("https://fontserver.xyz/test.woff") format("woff"),
    url("https://fontserver.xyz/test.ttf") format("truetype"),
    url("https://fontserver.xyz/test.svg#Test-Book") format("svg");
}
let fonts = {};

function getFontPairs(obj) {
  let object = obj || {},
    stylesheet = document.styleSheets,
    rule = null,
    length = stylesheet.length,
    j;
  while (0 <= --length) {
    rule = stylesheet[length].rules || stylesheet[length].cssRules || [];
    j = rule.length;
    while (0 <= --j) {
      if (rule[j].constructor.name === "CSSFontFaceRule") {
        let sourcesString = rule[j].style.src;
        let re = /\s*(?:,|$)\s*/;
        let sources = sourcesString.split(re);
        let final = [];

        sources.forEach(function(element){
        let reg = /[ ,]+/;
        let srcArray = element.split(reg);
        srcArray = srcArray.reverse();
        final.push(srcArray);
        });

       object[rule[j].style.fontFamily] = final;


      }
    }
  }
  return object;
}

getFontPairs(fonts);
console.log(fonts);

我尝试使用数组,但我的输出有点凌乱:Current array solution

相反,我希望实现这样的目标:Expected object solution

所以我现在不擅长RegEx,我想要脱掉url("")format("")as。我感谢任何帮助。也许有人可以帮助我提高代码的效率。

javascript css arrays regex javascript-objects
1个回答
0
投票

只需匹配每个源字符串中的url和格式。一个简单的正则表达式,正则表达式只匹配双引号或单引号内的内容,正则表达式的例子匹配url:

/url\(.(.+?).\)/

这意味着匹配url(..)之间的任何东西。 parens被逃脱,因此正则表达式不会将它们视为一组。 .(任何字符)代表引号(双打或单打)。 (.+?)是我们所关注的,网址,这是使用非gready模式?,以便它匹配尽可能少的字符,否则你可能最终得到一个网址:https://fontserver.xyz/test.eot?#iefix") format("embedded-opentype匹配从第一个引用到第二个(超出网址并进入格式区域)。

然后,要构建对象,只需将reduce的源代码转换为:

let sourcesObj = sources.reduce((acc, source) => {       // for each source
  let format = source.match(/format\(.(.+?).\)/)[1],     // get the format
      url = source.match(/url\(.(.+?).\)/)[1];           // and the url

  acc[format] = { format, url };                         // add them to the sourcesObj under the key format ({ format, url } is short for { format: format, url: url })
  return acc;
}, {});

完整代码:

function getFontPairs() {
  let object = {},
    stylesheet = document.styleSheets,
    rule = null,
    length = stylesheet.length,
    j;
  while (0 <= --length) {
    rule = stylesheet[length].rules || stylesheet[length].cssRules || [];
    j = rule.length;
    while (0 <= --j) {
      if (rule[j].constructor.name === "CSSFontFaceRule") {
        let sourcesString = rule[j].style.src;
        let sources = sourcesString.split(/\s*,\s*/);

        let sourcesObj = sources.reduce((acc, source) => {
          let format = source.match(/format\(.(.+?).\)/)[1],
              url = source.match(/url\(.(.+?).\)/)[1];

          acc[format] = { format, url };
          return acc;
        }, {});

        object[rule[j].style.fontFamily] = sourcesObj;
      }
    }
  }
  return object;
}

let fonts = getFontPairs();
console.log(fonts);

注意:url和format regex的更复杂的替代方法是:

/url(\s*["'](.+?)["']\s*)/

其中处理有url( "..." )等空格并寻找引号("')的情况是安全的。同样的事情可以应用于格式正则表达式。


编辑:

如果某个源有一个缺少的字段,那么在访问组[1]之前,只需检查格式和url正则表达式是否确实匹配了某些内容:

let sourcesObj = sources.reduce((acc, source) => {
  let format = source.match(/format\(.(.+?).\)/),
      url = source.match(/url\(.(.+?).\)/);

  if(format && url) {                                       // if and only if the two regexes matched what they are intended for
    acc[format[1]] = { format: format[1], url: url[1] };    // add the current source to 'sourcesObj' (notice the '[1]' is used after we've made sure that neither 'format' nor 'url' are 'null')
  }
  return acc;
}, {});

编辑2:

format缺失时,请替换为"Unknown"

let sourcesObj = sources.reduce((acc, source) => {
  let format = source.match(/format\(.(.+?).\)/),
      url = source.match(/url\(.(.+?).\)/)[1];

  format = format? format[1]: "Unknown";

  acc = { format, url };
  return acc;
}, {});
© www.soinside.com 2019 - 2024. All rights reserved.