.net 正则表达式:非任意非捕获组

.net 正则表达式:非任意非捕获组,.net,regex,.net,Regex,我想写正则表达式来涵盖我所有的案例。 我必须解析Xml并捕获一些属性。 例如: 我必须捕捉“p2”属性的价值,我知道“p2”将始终出现在队列中。 此外,我还想捕获“p4”属性的值,它并不总是存在 首先,我试图满足前四种情况(示例中的前四行),我编写了如下正则表达式: \<item.+?p2=\"(?<val1>\d+)".*?(?:p4=\"(?<val2>\d+)\")?\/\> \<item.+?p2=\"(?<val1>\d+)"

我想写正则表达式来涵盖我所有的案例。 我必须解析Xml并捕获一些属性。 例如:


我必须捕捉“p2”属性的价值,我知道“p2”将始终出现在队列中。 此外,我还想捕获“p4”属性的值,它并不总是存在

首先,我试图满足前四种情况(示例中的前四行),我编写了如下正则表达式:

\<item.+?p2=\"(?<val1>\d+)".*?(?:p4=\"(?<val2>\d+)\")?\/\>
\<item.+?p2=\"(?<val1>\d+)".*?(?:p4=\"(?<val2>\d+)\")?.*?\/\>
______________________________________________________^^^
\
而且效果很好。“val1”组始终返回值。如果显示“p4”属性,“val2”组将返回值

但为了涵盖我的最后一个案例:

<item p1="1" p2="2" p3="3" p4="4" p5="5"/>

我对正则表达式进行了如下修改:

\<item.+?p2=\"(?<val1>\d+)".*?(?:p4=\"(?<val2>\d+)\")?\/\>
\<item.+?p2=\"(?<val1>\d+)".*?(?:p4=\"(?<val2>\d+)\")?.*?\/\>
______________________________________________________^^^
\
______________________________________________________^^^
我发现“val1”组仍然返回值,但“val2”组不再返回所有情况下的值

你能告诉我我错过了什么,并帮助我写正则表达式来涵盖我所有的情况吗

XML不是一种好方法,因为使用正则表达式不是一种好方法。您还需要一个新的解决方案

有很多方法可以做到这一点,但就我个人而言,我会将XML文档加载到一个类中,并在查询中使用该方法来查找项目列表。一旦有了这些数据,就可以对每个找到的数据使用foreach,并使用集合获取所需的数据

如果你必须用正则表达式来做这件事,你需要做的就是把它放在最后。?在非捕获组中。您所做的是授予正则表达式ommit p4补丁和匹配的权限。?相反通过把它放进去?在团队内部,它消除了这种可能性。这可能很慢(甚至可能会受到影响),而且它无法处理XML的所有复杂性。下面是一个演示以下特性的程序:

using System;
using System.Text.RegularExpressions;

class Program
{
    static void Main()
    {
        var regex = new Regex(@"
        \<item                  # Capture <item
        .+?                     # Capture one or more characters as few times as possible 
        p2=                     # Capture p2=
        \""                     # Capture opening quote
        (?<val1>\d+)            # Capture one or more decimal digits and put them in val1
        ""                      # Capture closing quote
        .*?                     # Capture zero or more characters as few times as possible
        (?:                     # Begin a non capturing group
            p4=                 # Capture p4=
            \""                 # Capture opening quote
            (?<val2>\d+)        # Capture one or more decimal digits and put them in val2
            \""                 # Capture closing quote
            .*?                 # Capture zero or more characters as few times as possible
        )?                      # Capture 0 or 1 p4s        
        />                      # Capture \>
        ", RegexOptions.IgnorePatternWhitespace);

        Test(regex, @"<item p2=""2""/>", "2", string.Empty);
        Test(regex, @"<item p1=""1"" p2=""2""/>", "2", string.Empty);
        Test(regex, @"<item p1=""1"" p2=""2"" p3=""3""/>", "2", string.Empty);
        Test(regex, @"<item p1=""1"" p2=""2"" p3=""3"" p4=""4""/>", "2", "4");
        Test(regex, @"<item p1=""1"" p2=""2"" p3=""3"" p4=""4"" p5=""5""/>", "2", "4");
    }

    static void Test(Regex regex, string test, string p2, string p4)
    {
        Match m = regex.Match(test);

        string p2Group = m.Groups["val1"].Value;
        string p4Group = m.Groups["val2"].Value;

        Console.WriteLine("Test: '{0}'", test);
        Console.WriteLine("p2: '{0}' - {1}", p2Group, p2Group == p2 ? "Success" : "Fail");
        Console.WriteLine("p4: '{0}' - {1}", p4Group, p4Group == p4 ? "Success" : "Fail");
    }
}
使用系统;
使用System.Text.RegularExpressions;
班级计划
{
静态void Main()
{
var regex=新的regex(@“
\
“,RegexOptions.IgnorePatternWhitespace);
测试(regex,@“2”,string.Empty);
测试(regex,@“2”,string.Empty);
测试(regex,@“2”,string.Empty);
测试(正则表达式,@“,”2“,”4“);
测试(正则表达式,@“,”2“,”4“);
}
静态无效测试(正则表达式、正则表达式、字符串测试、字符串p2、字符串p4)
{
匹配m=正则表达式匹配(测试);
字符串p2Group=m.Groups[“val1”].Value;
字符串p4Group=m.Groups[“val2”].Value;
WriteLine(“Test:'{0}',Test);
WriteLine(“p2:'{0}'-{1}”,p2Group,p2Group==p2?“成功”:“失败”);
WriteLine(“p4:'{0}'-{1}”,p4Group,p4Group==p4?“成功”:“失败”);
}
}

我没有投你反对票,但你最好把时间花在学习使用XML解析器上。正则表达式不太适合XML解析。在这里使用正则表达式会很麻烦。你能保证这些参数总是按相同的顺序排列吗?如果没有,你将不得不对每一个可能的订单进行替换。使用XML解析器将更加明智和安全。我知道编写正则表达式来解析XML不是一个好主意。我已经在用其他工具实现它了。但是当我的第一个实现发现这种行为时,我想知道如何通过regex实现它。若你们愿意的话,我可以不使用Xml重写这个例子。并没有必要,只要这不出现在生产代码中,你们就可以对正则表达式感兴趣。但是您可能想知道,在询问有关regex+XML的问题时,您会收到系统性的反对票和劝阻性评论。我对.NET regex的味道一点也不熟悉,但您可能想尝试使用
?+
所有格量词作为
p4
片段,而不是简单的
。我知道这一点编写正则表达式来解析Xml不是一个好主意。我已经在用其他工具实现它了。但是当我的第一个实现发现这种行为时,我想知道如何通过regex实现它。如果你愿意,我可以重写没有Xml的例子。写没有Xml的例子,我会给你一个更好的答案。非常感谢,这正是我想要的。对不起,我甚至不能点击“这个答案很有用”,因为我没有足够的声誉。