正则表达式匹配<key> .... <value> pattern </value> </key>

时间:2010-07-06 07:36:03

标签: .net xml regex parsing

我有一个外部系统发送的以下数据,需要为特定的密钥

进行解析
<ContextDetails>
<Context><Key>ID</Key><Value>100</Value></Context>
<Context><Key>Name</Key><Value>MyName</Value></Context>
</ContextDetails>

我尝试用正则表达式解析它以获取KEY:Name

的值

<Context><Key>Name</Key><Value>.</Value></Context>

但结果为空白

我需要做些什么来修复这个正则表达式

5 个答案:

答案 0 :(得分:5)

如果这是XML,请将其加载到XDocument并查询。

有关如何执行此操作的详细信息,请参阅@Jens的answer

答案 1 :(得分:3)

要扩展Oded's answer,你应该这样做的方式是这样的:

XDocument doc = XDocument.Parse(@"<ContextDetails> 
<Context><Key>ID</Key><Value>100</Value></Context> 
<Context><Key>Name</Key><Value>MyName</Value></Context> 
</ContextDetails>");

String name  =  doc.Root.Elements("Context")
                        .Where(xe => xe.Element("Key").Value == "Name")
                        .Single()
                        .Element("Value").Value;

答案 2 :(得分:1)

我认为,Reg-Ex表达式与您所有的Key-Value-Pairse匹配是:

<Context>\s*?<Key>(.*?)\</Key>\s*?<Value>(.*?)</Value>\s*?</Context>

说明

// <Context>\s*?<Key>(.*?)\</Key>\s*?<Value>(.*?)</Value>\s*?</Context>
// 
// Match the characters "<Context>" literally «<Context>»
// Match a single character that is a "whitespace character" (spaces, tabs, line breaks, etc.) «\s*?»
//    Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
// Match the characters "<Key>" literally «<Key>»
// Match the regular expression below and capture its match into backreference number 1 «(.*?)»
//    Match any single character that is not a line break character «.*?»
//       Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
// Match the character "<" literally «\<»
// Match the characters "/Key>" literally «/Key>»
// Match a single character that is a "whitespace character" (spaces, tabs, line breaks, etc.) «\s*?»
//    Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
// Match the characters "<Value>" literally «<Value>»
// Match the regular expression below and capture its match into backreference number 2 «(.*?)»
//    Match any single character that is not a line break character «.*?»
//       Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
// Match the characters "</Value>" literally «</Value>»
// Match a single character that is a "whitespace character" (spaces, tabs, line breaks, etc.) «\s*?»
//    Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
// Match the characters "</Context>" literally «</Context>»

用法:

using System.Text.RegularExpressions;
public static void RunSnippet()
    {
        Regex RegexObj = new Regex("<Context>\\s*?<Key>(.*?)\\</Key>\\s*?<Value>(.*?)</Value>\\s*?</Context>",
            RegexOptions.IgnoreCase | RegexOptions.Multiline);
        Match MatchResults = RegexObj.Match(@"<ContextDetails>
            <Context><Key>ID</Key><Value>100</Value></Context>
            <Context><Key>Name</Key>   <Value>MyName</Value></Context>
            </ContextDetails>
            ");
        while (MatchResults.Success){
            Console.WriteLine("Key: " + MatchResults.Groups[1].Value)   ;
            Console.WriteLine("Value: " + MatchResults.Groups[2].Value) ;
            Console.WriteLine("----");
            MatchResults = MatchResults.NextMatch();
        }
    }
    /*
    Output:

        Key: ID
        Value: 100
        ----
        Key: Name
        Value: MyName
        ----
    */

正则表达式仅计算值或键“名称”:

<Context>\s*?<Key>Name</Key>\s*?<Value>(.*?)</Value>\s*?</Context>

说明

// <Context>\s*?<Key>Name</Key>\s*?<Value>(.*?)</Value>\s*?</Context>
// 
// Match the characters "<Context>" literally «<Context>»
// Match a single character that is a "whitespace character" (spaces, tabs, line breaks, etc.) «\s*?»
//    Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
// Match the characters "<Key>Name</Key>" literally «<Key>Name</Key>»
// Match a single character that is a "whitespace character" (spaces, tabs, line breaks, etc.) «\s*?»
//    Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
// Match the characters "<Value>" literally «<Value>»
// Match the regular expression below and capture its match into backreference number 1 «(.*?)»
//    Match any single character that is not a line break character «.*?»
//       Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
// Match the characters "</Value>" literally «</Value>»
// Match a single character that is a "whitespace character" (spaces, tabs, line breaks, etc.) «\s*?»
//    Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
// Match the characters "</Context>" literally «</Context>»

用法:

string SubjectString = @"<ContextDetails>
            <Context><Key>ID</Key><Value>100</Value></Context>
            <Context><Key>Name</Key>   <Value>MyName</Value></Context>
            </ContextDetails>
            ";
    Console.WriteLine( Regex.Match(SubjectString, "<Context>\\s*?<Key>Name</Key>\\s*?<Value>(.*?)</Value>\\s*?</Context>",
            RegexOptions.IgnoreCase | RegexOptions.Multiline).Groups[1].Value );

答案 3 :(得分:1)

在我看来,你做错了。您应该使用XML Parser。 http://www.tutorialspoint.com/ruby/ruby_xml_xslt.htm 这只是一个指南。它可以帮助。

答案 4 :(得分:0)

您可以使用XML解析器吗?如果是这样,那么使用它,这是这项工作的正确工具。

如果您只是拥有一个文本编辑器,并且愿意手动检查每个匹配项,那么您可以使用正则表达式。正则表达式中的错误是.只匹配一个字符(除了换行符之外的任何字符)。因此,您需要将.*?替换为{匹配任意数量的字符,但尽可能少,或者更好地[^<]*

后者表示“除<以外的零个或多个字符”(这是分隔字符)。当然,只有在您正在寻找的值中没有<时,这才有效。

你的正则表达式还假设整个匹配在一行上,标记之间没有空格 - 所以在所有其他情况下都会失败。

更新:我刚看到你的编辑:你确实可以访问XML解析器了 - 跟Oded的答案一起去。