2010-07-06 103 views
1

我具有由需要被解析爲特定的密鑰正則表達式匹配<Key> .... <Value>圖案

<ContextDetails> 
<Context><Key>ID</Key><Value>100</Value></Context> 
<Context><Key>Name</Key><Value>MyName</Value></Context> 
</ContextDetails> 

我試圖與正則表達式語法分析此來獲取值的外部系統發送的以下數據對於重點:名稱

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

但結果卻是空白

什麼是通道安格我需要做什麼來解決這個問題的正則表達式

+5

你不應該使用正則表達式這個.. – ant 2010-07-06 07:38:16

+2

這看起來並不像一個正則表達式我 - 什麼語言你用的是正則表達式嗎? Java的? 。淨? JavaScript的? Perl的?紅寶石?還有別的嗎? – Oded 2010-07-06 07:39:04

+3

看起來像XML解析器的完美工作。 – 2010-07-06 07:39:41

回答

5

如果這是XML,請將其加載到XDocument並進行查詢。

請參閱@Jens的answer以瞭解有關如何執行此操作的詳細信息。

1

我想,註冊-Ex的表達式匹配的所有鍵 - 值Pairse你是whant是:

<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 
     ---- 
    */ 

的正則表達式來僅數學的價值或鍵「name」:

<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); 
+0

哇,這是一個解釋! =)請問你是否使用了一些發生器來爲你做這件事?這會非常方便! – Jens 2010-07-06 07:51:34

+0

RegExBuddy是解釋的生成器。它帶有調試器的RegEx編輯器有更多的變化。 (網址:http://www.regexbuddy.com/) – Floyd 2010-07-06 07:58:47

0

你可以使用XML解析器?如果是這樣,那麼使用它,這是這份工作的正確工具。

如果你只是有一個文本編輯器,並且願意手工檢查每一個匹配,那麼你可能會使用正則表達式。您的正則表達式中的錯誤是.只匹配一個字符(除換行符外的任何字符)。所以你需要用.*?來代替(匹配任意數量的字符,但儘可能少),或者更好的是,[^<]*

後者表示「零個或多個字符,除了<」(這是分隔字符)。當然,這隻能在你正在尋找的值內沒有<的情況下才有效。

你的正則表達式還假設整個匹配是在一行中,標籤之間沒有空白 - 所以它在其他情況下都會失敗。

更新:我剛剛看到您的編輯:您可以訪問XML解析器,然後 - 與Oded的答案一起。

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;