разобрать мой собственный формат строки - PullRequest
4 голосов
/ 28 мая 2010

Как мы можем получить числа 7 и 4 и 5 из следующей строки:

MODULE potmtpMAIN main <info: "Enterprise Optimizer 7.4 for COR Technology 5.5 --    
Advanced Solver Edition", url:"http://EO.riverlogic.com", url_menu:"EO Online...",  
app_id:"EOAS",app_name:"Enterprise Optimizer AS", app_major:7,  
app_minor:4,app_micro:5,app_copyright:"\251 1996-2010 River Logic Inc.\r\nAll 
Rights Reserved."> 

Поиск должен быть основан на app_major: app_minor: и app_micro

Заранее спасибо

Ответы [ 5 ]

5 голосов
/ 28 мая 2010

Я сделал это с помощью LINQ ... может быть, это не самый лучший способ, но было интересно узнать это:

string test = "<info:\"Enterprise Optimizer 7.4 for COR Technology 5.5 -- Advanced Solver Edition\", url:\"http://EO.riverlogic.com\", url_menu:\"EO Online...\", app_id:\"EOAS\",app_name:\"Enterprise Optimizer AS\", **app_major:7**, **app_minor:4**,**app_micro:5**,app_copyright:\"251 1996-2010 River Logic Inc.\r\nAll Rights Reserved.\">";

var result = test.Split(',').
    Select(p => p.Trim().Split(':')).
    Where(i => i[0].Trim().StartsWith("**app_")).
    Select(r => new { Key = r[0].Trim('*'), Value = r[1].TrimEnd('*') });

Производит:

result = {{Key = "app_major", Value = "7"},
          {Key = "app_minor", Value = "4"}, 
          {Key = "app_micro", Value = "5"}}

Возможно, это даже можно сделать более элегантно:)

РЕДАКТИРОВАТЬ: Если вы хотите сделать очень простой доступ к тому, что вы хотите сделать:

var result = test.Split(',').
    Select(p => p.Trim().Split(':')).
    Where(i => i[0].Trim().StartsWith("**app_")).
    Select(r => new { Key = r[0].Trim('*'), Value = r[1].TrimEnd('*') }).
    ToDictionary(k => k.Key, v => v.Value);

Затем, чтобы получить значение, просто дайте ему ключ вот так:

var version = result["app_major"] ?? "Not Found";

Примечание. Я протестировал решение LINQ против решения Regex, и версия LINQ не так уж сильно отличается по скорости, но он немного медленнее, чем опубликованные ответы regex. Ответ regex, однако, не очищает данные для вас и представляет их в удобной форме. Часть ToDictionary действительно замедляет ее (с точки зрения реального времени, хотя она почти ничего не меняет), но облегчает использование результатов.

3 голосов
/ 28 мая 2010

с регулярным выражением (?<=:)\d(?=\*\*)

Отредактировано : Как редактируется вопрос, так и ответ. (?<=(app_major|app_minor|app_micro):)\d*

3 голосов
/ 28 мая 2010

Просто сделайте Regex, что-то вроде app_m....:\d может сработать, но я не уверен (я обычно использую один из инструментов, таких как RegexBuilder, чтобы сделать их).

В документации для Regex.Match есть пример, показывающий, как написать реальный код для использования регулярного выражения:

http://msdn.microsoft.com/en-us/library/twcw2f1c.aspx

Редактировать: что-то вроде этого может работать:

Match m = Regex.Match(mystring, "app_major:\d{1-2}");
if(m.Success)
{
     string appMajor = m.Value.SubString(m.Value.IndexOf(":"));
}

Если я правильно помню, бит \d{1-2} должен означать, что вы хотите получить одну или две цифры.

2 голосов
/ 28 мая 2010

Вот простое регулярное выражение для выбора каждой части, с примером кода для кого-то, незнакомого с регулярными выражениями в .NET: (Отредактировано, поскольку исходный вопрос был отредактирован для удаления звездочек).

Regex Exp = new Regex(@"(?<=\W)app_major:(?'Number'\d+)");

Match M = Exp.Match(input);

if(M.Success)
{
    string Number = M.Groups["Number"].Value;
}

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

Пояснение:

  • Первая часть (?<=\W) гарантирует, что совпадению предшествует несловесный символ (в этом случае, скорее всего, запятая).
  • Вторая часть app_major: соответствует буквальной части искомой строки.
  • (?'Number'\d+) - это захваченная группа, которую мы помечаем Number, где мы пытаемся сопоставить одну или несколько цифр \d+.
2 голосов
/ 28 мая 2010

Используйте регулярное выражение:

string regex = @"app_major:(?<major>\d+).*app_minor:(?<minor>\d+).*app_micro:(?<micro>\d+";
   RegexOptions options =        
      (RegexOptions.IgnorePatternWhitespace | 
      RegexOptions.Singleline | 
      RegexOptions.Multiline  | 
      RegexOptions.IgnoreCase);

Regex reg = new Regex(regex, options);

Match match = reg.Matches(yourString);

string major = match.Groups[1].Value
string minor = match.Groups[2].Value
string micro = match.Groups[3].Value
...