2011-09-01 48 views
3

我有很長的字符串,它們是IMAP請求的響應,我想從中提取一些值。它通常被格式化爲「x someword」或「someword x」 - 如何讓某個詞(已知)得到x(可以是多個數字)?響應的每個「行」看起來像:從C#中的某個單詞之前/之後的字符串中過濾值#

* x someword \r\n 

和我的字符串包含這幾行。提取期望值的最簡單方法是什麼?

示例: 爲 「* X WORD1 \ r \ n * Y WORD2 \ r \ n」 個,與WORD2作爲參數我想得Y

所有響應例如:

* FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)\r\n* OK [PERMANENTFLAGS()] Flags permitted.\r\n* OK [UIDVALIDITY xxx] UIDs valid.\r\n* 3 EXISTS\r\n* 0 RECENT\r\n* OK [UIDNEXT x] Predicted next UID.\r\n. OK [READ-ONLY] INBOX selected. (Success)\r\n 

對於 「是否存在」 我想3

回答

1

我會用正則表達式...這裏是你可以做什麼:

string myString = "* FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)\r\n* OK [PERMANENTFLAGS()] Flags permitted.\r\n* OK [UIDVALIDITY 657136382] UIDs valid.\r\n* 3 EXISTS\r\n* 0 RECENT\r\n* OK [UIDNEXT 4] Predicted next UID.\r\n. OK [READ-ONLY] INBOX selected. (Success)\r\n"; 

string myWordToFind = "EXISTS"; 

string result = Regex.Match(myString, @"(?<MyNumber>\d+)\s*(" + Regex.Escape(myWordToFind) + ")", 
    RegexOptions.Compiled | RegexOptions.IgnoreCase) 
    .Groups["MyNumber"].Value; 
+0

我自己做過這件事:recentfilter = @「\ d {1,} EXISTS」; mc = Regex.Matches(response,recentfilter); recent = Int32.Parse(mc [0] .Value.Replace(「EXISTS」,String.Empty));你能告訴我是否有任何大的差異或一些潛在的問題嗎? – deha

+0

'\ d {1,}'與'\ d +'相同,'\ d +'語法更通用,因爲它的更短。你的代碼會有類似的效果,但是你多次解析你的輸入字符串,你最好使用命名捕獲來實現性能。 –

+0

感謝您的回答。其他人也很棒 – deha

1

所以給出: X markerWord \ n \ rmarkerWordŸ

你想{X,Y}? 如果是這樣,請嘗試先按行分割,然後再簡單地移除「markerWord」。

事情大致是這樣:

var result = input.Split(new[]{'\n', '\r'}).Select(line => line.Replace("markerWord", string.Empty); 

更新答案: 那好吧,我會用正則表達式。概念的簡單的證明,我敢肯定,你可以把它從這裏:

static string GetParam(string input, string param) { 
      var pattern = new Regex(@"[\\*](?<value>.+)" + param); 
      var split = input.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries); 
      var line = split.SingleOrDefault(l => pattern.IsMatch(l)); 
      if(line != null) { 
       return pattern.Match(line).Groups["value"].Value.Trim(); 
      } 
      return null; 
     } 
+0

不,我在字符串中有一個「* ... \ r \ n」的序列。在一些序列中,我有這樣的:3最近(所以這一行「是」:* 3 RECENT \ r \ n),我需要得到參數RECENT – deha

+0

的整數3,並且是所有行上的關鍵字RECENT ?請發佈一個完整的樣本和預期的輸出。 – chrisaut

+0

@deha請編輯問題並在那裏添加回復。 – Reniuz

1
class Class1 
{ 
    string str = "* FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)\r\n* OK [PERMANENTFLAGS()] Flags permitted.\r\n* OK [UIDVALIDITY 657136382] UIDs valid.\r\n* 3 EXISTS\r\n* 0 RECENT\r\n* OK [UIDNEXT 4] Predicted next UID.\r\n. OK [READ-ONLY] INBOX selected. (Success)\r\n"; 

    public void FindString(string parm) 
    { 
     if (str.Contains(parm)) 
     { 
      string[] parts = str.Split('*'); 
      foreach (var item in parts) 
      { 
       if (item.Contains(parm)) 
       { 
        string[] values = item.Split(' '); 
        string value = values[1]; 
       } 
      } 
     } 
    } 

    static void Main(string[] args) 
    { 
     Class1 c = new Class1(); 
     c.FindString("EXISTS"); 
    } 
} 
1

您應該使用此

Regex r=new Regex(@"(?<value>\d+)\s*(?<keyword>EXISTS|RECENT)"); 

foreach (var match in r.Matches(source).OfType(Match)) { 
    var parameter=int.Parse(match.Groups["value"].Value); 
    switch (match.Groups["keyword"].Value) { 
    case "EXISTS": 
     doExists(parameter); 
     break; 
    case "RECENT": 
     doRecent(parameter); 
     break; 
    } 
} 
1

一個正則表達式,您可以使用下面的(希望,不言自明)代碼:

const string response [email protected]" 
    * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) 
    * OK [PERMANENTFLAGS()] Flags permitted. 
    * OK [UIDVALIDITY 657136382] UIDs valid. 
    * 3 EXISTS 
    * 0 RECENT 
    * EXISTS 4  <------------------- another occurence of the word 
    * OK [UIDNEXT 4] Predicted next UID. 
    * OK [READ-ONLY] INBOX selected. (Success)"; 

    string word = "EXISTS"; 
    string pattern = 
     Regex.Escape(word) + // the word to find followed by... 
     @" 
     \s+   (?# one ore more space characters followed by...) 
     (?<num>\d+) (?# one or more digits.) 

     |   (?# Or) 

     (?<num>\d+) (?# one or more digits, then...) 
     \s+   (?# one ore more space characters followed by...)" 
     + Regex.Escape(word); // the word to find. 

    foreach (Match match in Regex.Matches(response, pattern, RegexOptions.Multiline | RegexOptions.IgnorePatternWhitespace)) 
    { 
     Console.WriteLine(match.Groups["num"]); 
    } 
相關問題