.net 正则表达式:非任意非捕获组
我想写正则表达式来涵盖我所有的案例。 我必须解析Xml并捕获一些属性。 例如:.net 正则表达式:非任意非捕获组,.net,regex,.net,Regex,我想写正则表达式来涵盖我所有的案例。 我必须解析Xml并捕获一些属性。 例如: 我必须捕捉“p2”属性的价值,我知道“p2”将始终出现在队列中。 此外,我还想捕获“p4”属性的值,它并不总是存在 首先,我试图满足前四种情况(示例中的前四行),我编写了如下正则表达式: \<item.+?p2=\"(?<val1>\d+)".*?(?:p4=\"(?<val2>\d+)\")?\/\> \<item.+?p2=\"(?<val1>\d+)"
我必须捕捉“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的例子,我会给你一个更好的答案。非常感谢,这正是我想要的。对不起,我甚至不能点击“这个答案很有用”,因为我没有足够的声誉。