繁体   English   中英

如何将文本匹配为键值对

[英]How to match text between as key-value pairs

我需要一个 RegExp 来评估 CSS 代码; 匹配选择器、显示名称和属性。 我对正则表达式不太熟悉,所以我有这个表达式可以匹配选择器 - 如果存在 - 并显示名称: /(?'selector'\#|\.?)(?'display'[a-zA-Z][a-zA-Z]*)\s*(?=\{)(.*?)(?=\})/gm

我已经设法匹配选择器和显示组,我不能做的是匹配属性。 例如,在下面的字符串中,我想匹配中有一个组,它将返回background: red和另一个返回color: green的组。

我可以将分隔符( {} )之间的内容与前瞻和后视相匹配,但我无法在匹配中创建组来提取我的属性。

我在这个字符串上测试这些: #id { background: red; color: green; } #id { background: red; color: green; }

需要明确的是,我对这个字符串的期望结果是:

  1. 选择器(工作)
  2. 姓名(工作)
  3. 第一个属性(在这种情况下,这个值应该是background: red
  4. 第二个属性(在这种情况下,这个值应该是color: green
  5. 其他属性(如果存在)

我不会尝试在单个复杂的正则表达式中分解整个 CSS 规则,而是编写一个使用更简单的正则表达式的简单解析器。

CSS 规则由明确定义的独立部分组成:
一个选择器[1] 、一个左大括号“{”、一些声明和一个右大括号“}”

<selector> '{'
    <declaration>';'*
'}'

声明是一个属性,一个冒号':',,然后是一个分号';'

使用这些关键字符{:;}我们可以使用三个简单的正则表达式将规则拆分为多个部分。
第一个正则表达式乍一看有点复杂,因为它考虑了可选的空格,所以在几个地方使用了\s*

/^\s*(?<selector>[^{]+)\s*{\s*(?<declarations>.+)\s*}/ms

但它基本上只是寻找和分离选择器和一些用大括号括起来的声明{...}
请注意,它使用多行搜索m并且还使用“dotAll”选项s ,因此它可以匹配 CSS 规则,因为它们通常在多行上编写。

一旦有了这些,它就会使用简单的字符串.split来分解每个声明。 声明以分号结尾,因此它将执行.split(/\s*;\s*/)生成声明数组。 每个声明都是property:value对,因此将在冒号:上拆分并解构结果数组: [property, value] = declaration.split(/\s*:\s*/)

我使用将 CSS 规则作为字符串并返回代表选择器和所有声明的 object 的步骤创建了 function。

 const ruleA = '#id { background:red; color: green; }'; const ruleB = `#id { background: red; color:green; }`; let parsedRule = parseRule(ruleB); console.log('parsedRule:', parsedRule); function parseRule(rule) { const re_rule = /^\s*(?<selector>[^{]+)\s*{\s*(?<declarations>.+)\s*}/ms; const base = re_rule.exec(rule); const selector = base.groups.selector.trim(); const declarations = base.groups.declarations.trim(); const result = { 'selector': selector, 'declarations': [] }; declarations.split(/\s*;\s*/).forEach(d => { [property, value] = d.split(/\s*:\s*/); //console.log('prop length:', property.length); //console.log(`property: '${property}'`); //console.log(`value:' '${value}'`); if (property?.trim().length > 0) { result.declarations.push({ "prop": property, "value": value }); } }); return result; }

[1] 当然,“一个选择器”可以是多个逗号分隔的选择器,并且可以处理,但我省略了它以使这个示例更简单,并且希望更清晰。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM