【问题标题】:Regex example to match pseudo element's content property匹配伪元素内容属性的正则表达式示例
【发布时间】:2018-07-04 17:37:56
【问题描述】:

我正在尝试解析 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 和字符串内容(顺序很重要,因为我想稍后用评估值替换它们)

如果需要更多信息,请告诉我。 谢谢

【问题讨论】:

    标签: javascript regex pseudo-element regex-lookarounds


    【解决方案1】:

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

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

    counter\([^)]*\)
    

    它匹配一个文字counter(,然后是零个或多个非右括号,最后是一个右括号。 (your first regexmy simpler version 在 regex101 的完整解释。)

    我相信这回答了您的第一个问题,但如果您实际上是在寻找“匹配 [a] 单括号的正则表达式”,那就是 [()],它将匹配左括号或右括号字符。如果您知道要匹配哪一个,也可以显式匹配 \(\)

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

    "[^"]*"
    

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

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

    我不确定你打算如何获得 CSS content property 的值,因为它通常在 ::after::before 伪类中,它们是 not available from the DOM,但这里有一些填充的虚拟代码以便我们可以操纵它:

    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 属性(最后一个是因为它会覆盖以前的实例,但请注意这会愚蠢地从 content: "content: blah" 中提取 content: blah)。在找到分词符的最后一个实例,然后找到content: 之后,它会吸收所有空格,然后匹配行的其余部分,直到分号、双引号或单引号。非捕获组允许双引号或单引号之间的任何内容,这与我们在此答案顶部附近匹配引号的方式非常相似。 (this CSS content regex 在 regex101 的完整解释。)

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

    【讨论】:

    • 感谢您的回复,Counter 不能有嵌套括号(即 counter(item (somevalue)) 是不可能的),它只能有一个左括号和右括号。 Css 内容属性可以有计数器、属性、字符串、url 和引号的任意组合。我需要正则表达式在稍后以给定的顺序解析相同的结果以替换为实际值。希望这对您有所帮助。如果您需要更多信息,请告诉我
    • @PavanTiwari – 你假设一个有效的CSS content 声明吗?我不会帮助您按照规范构建功能齐全的解析器,但我可以帮助您完成您所要求的四个项目。除此之外,您应该使用真正的 CSS 解析器,例如 HTMLelement.stylegetComputedStyle()
    • 再次感谢。 Javascript 不允许我们直接访问伪元素的值。所以我正在构建一个框架,它将首先解析内容,然后用评估值替换它们。 GetComputedStyle 只会给出 css 内容的使用声明值,而不是评估的值。
    • 你确定吗?这就是为什么它被称为 get Computed 风格;它“在应用活动样式表并解决这些值可能包含的任何基本计算后报告元素的所有 CSS 属性的值。” HTMLelement.style 只会为您提供 CSS 内容的声明值。 (这里的问题是单独的:DOM 不提供对伪元素的访问权限,因此您也无法获得它们的计算样式。)
    • 是否可以使用 /.*\bcontent:\s*([^;"']*(?:"[^"]*"[^;" ']*|'[^']*'[^;"']*)*)/ 像 [counter(item, decimal), ' ', attr(data)] 。对于输入字符串内容:counter(item, decimal)' ' attr(data)
    猜你喜欢
    • 2012-06-02
    • 1970-01-01
    • 2019-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多