фильтрация значений из строки после / перед определенным словом в c # - PullRequest
3 голосов
/ 01 сентября 2011

У меня довольно длинные строки, которые являются ответом на запрос IMAP, и я хочу извлечь из него некоторые значения.Обычно он форматируется как «x someword» или «someword x» - как получить x (это может быть больше, чем одна цифра) для someword (что известно)?Каждая «строка» ответа выглядит так:

* x someword \r\n

, и моя строка содержит пару этих строк.Какой самый простой способ извлечь нужные значения?

Пример: для "* x word1 \ r \ n * y word2 \ r \ n" со словом2 в качестве параметра, который я хочу получить 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

Для "EXISTS" я хочу получить 3.

Ответы [ 5 ]

1 голос
/ 01 сентября 2011

Вы можете использовать следующий (надеюсь, не требующий пояснений) код:

const string response =@"
    * 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"]);
    }
1 голос
/ 01 сентября 2011

Вы должны использовать регулярное выражение для этого

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 голос
/ 01 сентября 2011

Я бы использовал регулярные выражения ... вот что вы можете сделать:

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;
1 голос
/ 01 сентября 2011
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 голос
/ 01 сентября 2011

Так дано: X markerWord \ n \ rmarkerWord Y

Вы хотите {X, Y}? Если это так, попробуйте сначала разбить строки, а затем просто удалите "markerWord".

Что-то примерно так:

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

Обновленный ответ: Ну тогда я бы использовал Regex. Простое доказательство концепции, я уверен, что вы можете взять его отсюда:

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;
        }
...