C# 具有重叠匹配的多行正则表达式

C# 具有重叠匹配的多行正则表达式,c#,.net,css,regex,C#,.net,Css,Regex,我正在开发一个工具,用于解析CSS样式声明的文件。它使用了一个非常复杂的正则表达式,除了预期的性能问题和一些暂时不会影响我的小错误之外,它正在做我希望它做的一切,除了一件事 我让它匹配元素名、类、子类、伪类等的所有组合。但是,当一行包含多个声明时,我只能让它匹配一次。举个例子,现在有一件事让我大吃一惊: td.class1, td.class2, td.class3 { background-color: #FAFAFA; height: 10px; } 我可以为这三个声明编写

我正在开发一个工具,用于解析CSS样式声明的文件。它使用了一个非常复杂的正则表达式,除了预期的性能问题和一些暂时不会影响我的小错误之外,它正在做我希望它做的一切,除了一件事

我让它匹配元素名、类、子类、伪类等的所有组合。但是,当一行包含多个声明时,我只能让它匹配一次。举个例子,现在有一件事让我大吃一惊:

td.class1, td.class2, td.class3
{
    background-color: #FAFAFA;
    height: 10px;
}
我可以为这三个声明编写一个表达式来满足这一点,但因为我还捕获了后面的信息(括号内的实际样式信息)我觉得这整个文本块都被考虑在内了,所以引擎会转到刚刚处理的整个文本块后面的下一个字符

是否有一种方法可以实现这一点,即每个类都是单独的匹配项,并且都包含下面的样式信息?我知道我可以修改我的正则表达式以匹配整行,然后在得到匹配项后将其解析为逗号,但如果可能的话,我希望将所有逻辑都保留在表达式本身中


如果表达式与答案绝对相关,我可以发布表达式和/或我用来生成它的注释代码,但是表达式太大/太难看(所有非平凡的正则表达式都是如此),而且代码有点长

根据正则表达式引擎的细微差别,您可以通过在lookaheads中嵌入捕获参数来实现这一点,例如:

\.(\w+)(?=.*?{([^}]*)})

我希望找出匹配组的含义是一项相当艰巨的工作。

根据正则表达式引擎的细微差别,您可以通过在lookaheads中嵌入捕获参数来实现这一点,例如:

\.(\w+)(?=.*?{([^}]*)})

我希望弄清楚匹配组的含义是一个相当大的练习。

您需要的是CSS解析器,而不是正则表达式。您可能应该阅读。

您需要的是CSS解析器,而不是正则表达式。您可能应该阅读。

这对于正则表达式来说不是一个好问题

另一方面,当然,您只需要几遍就可以编写一个基本的CSS解析器

CSS语法毕竟只是[一些东西],[打开花括号],[一些其他东西],[关闭花括号]


找到这两块东西,第一块用逗号分割,第二块用分号分割,就差不多完成了。

这对正则表达式来说不是个好问题

另一方面,当然,您只需要几遍就可以编写一个基本的CSS解析器

CSS语法毕竟只是[一些东西],[打开花括号],[一些其他东西],[关闭花括号]


找到这两块东西后,第一块用逗号分割,第二块用分号分割,就差不多完成了。

这里有一个用于示例数据的正则表达式:

@"([^,{}\s]+(?:\s+[^,{}\s]+)*)(?=[^{}]*(\{[^{}]+\}))"
第一部分匹配并捕获组#1中的选择器(td.class1),然后先行跳过任何剩余的选择器并捕获组#2中的关联样式规则。下一次匹配尝试从前一次开始的地方开始,因此它匹配下一个选择器(td.class2),并且前一次再次捕获相同的规则块


这不会处理@规则或注释,但它在您提供的示例数据上运行良好。我甚至在一些真实世界的样式表上查看了它,它做得非常好。

这里有一个正则表达式,可以处理您的示例数据:

@"([^,{}\s]+(?:\s+[^,{}\s]+)*)(?=[^{}]*(\{[^{}]+\}))"
第一部分匹配并捕获组#1中的选择器(td.class1),然后先行跳过任何剩余的选择器并捕获组#2中的关联样式规则。下一次匹配尝试从前一次开始的地方开始,因此它匹配下一个选择器(td.class2),并且前一次再次捕获相同的规则块


这不会处理@规则或注释,但它在您提供的示例数据上运行良好。我甚至在一些真实世界的样式表上查看了它,它做得非常好。

我需要对AmbroseChapel所说的话有一个类似的看法,我需要它在AS3中,所以我正在分享它,以防它对其他人有帮助。我尽力做到彻底,这些评论会引导你完成整个过程。我在一些流行的CSS锅炉板上进行了测试,效果非常好。:)(这仅用于列出选择器名称,不用于属性解析。)

公共函数getSelector(targetCSS:String,includeElements:Boolean=true):ArrayCollection
{
var newSelectorCollection:ArrayCollection=newarraycollection();
如果(targetCSS==null | | targetCSS==“”)返回newSelectorCollection;
var newSelectors:Array=newarray();
变量元素:数组=新数组();
变量id:Array=newarray();
变量类:数组=新数组();
//删除评论
var cssString:String=“”;
var commentParts:Array=targetCSS.split(“/*”);
对于(var C:int=0;C<CopyPt.Stand;C++){
var comPart:String=commentParts[c]作为字符串;
var comTestArray:Array=comPart.split(“*/”);
如果(comTestArray.length>1){
comTestArray.shift();
comPart=comTestArray.join(“”);
}
cssString+=comPart;
}
//删除\n
cssString=cssString.split(“\n”).join(“”);
//删除\t
cssString=cssString.split(“\t”).join(“”);
//在}处拆分
var cssParts:Array=cssString.split(“}”);
for(变量i:int=0;i