正则表达式示例以匹配伪元素的content属性

时间:2018-07-04 17:37:57

标签: javascript regex pseudo-element regex-lookarounds

我正在尝试解析javascript中的伪选择器内容。 HTML内容可以是

content: counter(item)" " attr(data) "" counter(item1,decimal) url('test.jpeg') "hi" attr(xyz);

我正在使用下面的正则表达式(从互联网复制匹配括号的逻辑)来解析此内容

 counter\((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)

这将选择所有带有“(” 的计数器,但是计数器不能包含嵌套的括号(据我所知,如果我错了,请更正我)。同样,我使用正则表达式来选择其他内容。

  1. 属性:attr\((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)

  2. 行情:openQuote\((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)

  3. 字符串:双引号或单引号内的所有内容:(当前正则表达式无法正常运行“。*”

我在这里有以下问题 1.正则表达式匹配单个括号(伪选择器内容属性中不能嵌套括号) 2.将以给定顺序匹配计数器,属性,URL和字符串内容的单个正则表达式(顺序很重要,因为我想稍后用评估值替换它们)

请告知我是否需要其他信息。 谢谢

1 个答案:

答案 0 :(得分:1)

您的第一个正则表达式确实与嵌套括号匹配(但不与转义括号匹配)。这是可取的吗?

没有嵌套或转义,这些变得更加简单。
这是您第一个正则表达式的一种变体,它忽略了嵌套的可能性:

counter\([^)]*\)

它与文字counter(相匹配,然后与零个或多个非近圆括号匹配,最后与右圆括号匹配。 (有关regex101的your first regexmy simpler version的完整说明。)

我相信这可以回答您的第一个问题,尽管如果您实际上是在寻找“与[a]单个括号匹配的正则表达式”,那只是[()],它将与一个开放或封闭的括号匹配。如果您知道要匹配哪一个,也可以明确匹配\(\)

匹配引号(不考虑嵌套引号或转义引号)同样容易:

"[^"]*"

这将匹配文字双引号("),然后是零个或多个非双引号字符,然后是另一个文字双引号。

您的第二个请求是“按给定顺序匹配计数器,属性,URL和字符串内容的单个正则表达式(顺序很重要,因为我想稍后用评估值替换它们)”

我不确定您打算如何获得CSS content property的值,因为在::after::before伪类中通常是{{3} },但是下面是一些伪代码,因此我们可以对其进行操作:

var css = `content: counter(item)" " attr(data) "" counter(item1,decimal) url('test.jpeg') "hi" attr(xyz); color:red;`;

// harvest last `content` property (this is tricked by `content: "content: blah"`)
var content = css.match(/.*\bcontent:\s*([^;"']*(?:"[^"]*"[^;"']*|'[^']*'[^;"']*)*)/);
if (content) {
  var part_re = /(?:"([^"]*)"|'([^']*)'|(?:counter|attr|url)\(([^)]*)\))/g;
  while ( part = part_re.exec(content[1]) ) { // parse on just the value
    if      (part[0].match(/^"/))       { /* do stuff to part[1] */ }
    else if (part[0].match(/^'/))       { /* do stuff to part[2] */ }
    else if (part[0].match(/^counter/)) { /* do stuff to part[3] */ }
    else if (part[0].match(/^attr/))    { /* do stuff to part[3] */ }
    else if (part[0].match(/^url/))     { /* do stuff to part[3] */ }

    // silently skips other values, like `open-quote` or `counters(name, string)`
  }
}

第一个正则表达式(第4行)从CSS提取了最后一个content属性(最后一个原因是它将覆盖以前的实例,尽管请注意,这会从{{ 1}})。找到最后一个分词符然后是content: blah之后,它会吸收所有空格,然后匹配行的其余部分,直到分号,双引号或单引号为止。非捕获组允许双引号或单引号之间的任何内容,与我们在此答案顶部附近匹配引号的方式大致相同。 (有关regex101的not available from the DOM的完整说明。)

第二个正则表达式(分配给content: "content: blah"的第7行)处于while循环中,因此我们可以按顺序处理content:属性中的每个值。它匹配双引号字符串或单引号字符串或某些命名值(计数器或attr或url)。有关值数据的存储位置,请参阅条件和注释。 regex101中this CSS content regex的完整说明(请参阅右列中间的“匹配信息”,以了解如何存储值的数据)。