我正在使用正则表达式解析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", @""".*?(?<!\\)""|'.*?(?<!\\)'"},
};
答案 0 :(得分:1)
你不应该写一个正则表达式来解析整个事情。但首先得到选择器,然后为每个选择器获得组合器。 (至少你可以解析你的例子,真正的CSS会变得更复杂。)
答案 1 :(得分:1)
每次捕获确实为您提供了匹配发生位置的索引...也许我可以使用该信息来确定属于什么?
在这里大声思考;你可以挑选Selector
组中的每个匹配,获得相对于整个匹配的起始和结束索引,并查看每个组合子的索引是否在开始和结束索引范围内。如果组合子的索引落在该范围内,它将出现在该选择器中。
我不确定这在性能方面会如何。但我认为你可以让它发挥作用。
答案 2 :(得分:1)
我不建议使用正则表达式来解析任何东西。除了非常简单的情况,解析器几乎总是更好的选择。看看这个问题。