正则式分组应用

把一个字符串按","分组,要求","前不能有"\"转义.
比如有串@"a=a\bc,b=bc\\,c=cd"
分组后结果应该是一个长度为3的字符串组,
{@"a=a\bc",@"b=bc\\","c=cd"}

即,在逗号前面如果是偶数个\则其\就不为转义字符代表其本身\符号
如果前面是奇数个\则证明,符号是被转义的了代表,符号

现在命题要求的意思是如果,符号未被转义,就作为分隔符,如果被转义则忽略掉
root_的答案为:

(?<=[^\\](|(\\\\)+)),

其分解的含义就为匹配空隙前面必须是不为\的字符加上空字符或者是偶数个\字符

[^\\](|(\\\\)+)这个为总条件,我们分解一下得:
[^\\]非转义字符;
(|(\\\\)+)偶数个\字符或者为空

不过当我们分组时,我们会发现会额外的增加分组信息,即(\\\\)匹配到的内容和(|(\\\\)+)匹配到的内容
所以在分组时我们需要把其非命名分组的匹配信息丢弃掉.所以得设置参数RegexOptions.ExplicitCapture
最后的测试代码则为:
string test = @"a=a\,bc,b=bc\\,c=cd";
string[] result = Regex.Split(test, @"(?<=[^\\](|(\\\\)+)),", RegexOptions.ExplicitCapture);
foreach (string str in result)
  {
         MessageBox.Show(str);
   }

其实我最初的想法也是如上,不过想漏了一点.思维不够缜密哈
最初我是这样写的

(?<=(?:\\\\)),|(?<!\\),

这就是特殊应用式,也是指,号前面只能是\\或者不是\转义的匹配.
不过貌似正确.可其中还是有问题的,思路倒是正确,不过表达有点问题
起初一想就是扩展为偶数和奇数次\符号的判断也不难,把分组指定其次数就好

(?<=(\\\\)+),|(?<!\\),
这个也是貌似正确了,不过还考虑漏了一项,那就是在匹配到(\\\\)+分组以后,其前面还是\的情况

a=a\bc,b=bc\\\\\,c=cd
这种情况,所以还得加一重判断,你(\\\\)+分组之前的字符一定不能再是\符号
所以我们得出结果:
(?<!\\),|(?<=[^\\](\\\\)+),
这下问题解决了(不过这个方案和root_方案多少有些类似.不过思路都一致,只是我采用了一个?<!判断,而root只用了?<=就得出了结果,技能高人一等哈.
测试代码
string test = @"a=a\,bc,b=bc\\,c=cd";
            
string regex = "(?<!\\\\),|(?<=[^\\\\](\\\\\\\\)+),";
            
string[] result = Regex.Split(test, regex, RegexOptions.ExplicitCapture);
            
foreach (string str in result)
            {
                MessageBox.Show(str);
            }


^-^辛苦了好一阵了.
原文地址:https://www.cnblogs.com/symbol441/p/991771.html