如何获取给定Capture的Regex组?

时间:2011-05-08 23:01:04

标签: c# regex

我正在使用正则表达式解析CSS3选择器。例如,选择器a>b,c+d分解为:

  Selector:
    a>b
    c+d
  SOSS:
    a
    b
    c
    d
  TypeSelector:
    a
    b
    c
    d
  Identifier:
    a
    b
    c
    d
  Combinator:
    >
    +

问题是,例如,我不知道>组合器属于哪个选择器。 Selector组有2个捕获(如上所示),每个捕获包含1个组合子。我想知道该组合器对于该捕获是什么。

组有Captures列表,但是Captures没有在Capture中找到的组列表。有没有解决方法,或者我应该重新解析每个选择器?


编辑:每次捕获都会为您提供匹配发生位置的索引...也许我可以使用该信息来确定属于哪些内容?


所以你不觉得我疯了,语法实际上非常简单,使用我的特殊字典:

var flex = new FlexDict
    {
        {"GOS"/*Group of Selectors*/, @"^\s*{Selector}(\s*,\s*{Selector})*\s*$"},
        {"Selector", @"{SOSS}(\s*{Combinator}\s*{SOSS})*{PseudoElement}?"},
        {"SOSS"/*Sequence of Simple Selectors*/, @"({TypeSelector}|{UniversalSelector}){SimpleSelector}*|{SimpleSelector}+"},
        {"SimpleSelector", @"{AttributeSelector}|{ClassSelector}|{IDSelector}|{PseudoSelector}"},

        {"TypeSelector", @"{Identifier}"},
        {"UniversalSelector", @"\*"},
        {"AttributeSelector", @"\[\s*{Identifier}(\s*{ComparisonOperator}\s*{AttributeValue})?\s*\]"},
        {"ClassSelector", @"\.{Identifier}"},
        {"IDSelector", @"#{Identifier}"},
        {"PseudoSelector", @":{Identifier}{PseudoArgs}?"},
        {"PseudoElement", @"::{Identifier}"},

        {"PseudoArgs", @"\([^)]*\)"},

        {"ComparisonOperator", @"[~^$*|]?="},
        {"Combinator", @"[ >+~]"},

        {"Identifier", @"-?[a-zA-Z\u00A0-\uFFFF_][a-zA-Z\u00A0-\uFFFF_0-9-]*"},

        {"AttributeValue", @"{Identifier}|{String}"},
        {"String", @""".*?(?<!\\)""|'.*?(?<!\\)'"},
    };

3 个答案:

答案 0 :(得分:1)

你不应该写一个正则表达式来解析整个事情。但首先得到选择器,然后为每个选择器获得组合器。 (至少你可以解析你的例子,真正的CSS会变得更复杂。)

答案 1 :(得分:1)

  

每次捕获确实为您提供了匹配发生位置的索引...也许我可以使用该信息来确定属于什么?

在这里大声思考;你可以挑选Selector组中的每个匹配,获得相对于整个匹配的起始和结束索引,并查看每个组合子的索引是否在开始和结束索引范围内。如果组合子的索引落在该范围内,它将出现在该选择器中。

我不确定这在性能方面会如何。但我认为你可以让它发挥作用。

答案 2 :(得分:1)

我不建议使用正则表达式来解析任何东西。除了非常简单的情况,解析器几乎总是更好的选择。看看这个问题。

Is there a CSS parser for C#?