2015-03-15 2 views
0

Прямо к точке. Я работаю над ботром IRC, и я нахожусь на кирпичной стене, с которой я стучал головой с 4 утра этим утром.Линии поиска, ориентированные на регулярные выражения, в любом порядке и могут быть или не существовать

Я пытаюсь сортировать строки IRC Raw 005 (IS_SUPPORTED) специально для групп регулярных выражений. Пример строки выглядит следующим образом.

Nickname MAXTARGETS=20 WALLCHOPS WATCH=128 WATCHOPTS=A SILENCE=15 MODES=12 CHANTYPES=# PREFIX=(qaohv)~&@%+ CHANMODES=beI,kfL,lj,psmntirRcOAQKVCuzNSMTGZ NETWORK=Network CASEMAPPING=ascii EXTBAN=~,qjncrRa ELIST=MNUCT 

я очищал остальную часть пакета на данный момент, так что эта линия является именно то, что я работаю с, хотя могут быть и другие поля, не показанные в моем примере. У меня есть строки, все имена которых указаны после каждого из возможных полей, которые могут быть в этом пакете. Я хотел бы установить каждый из строк, Интса и BOOLS каждые из полученной информации, отсортированной по регулярным выражениям групп в C#

Чтобы быть более ясными,

  • Моим public int maxtargets будет установлен в результате регулярных выражений group <maxtargets>
  • Мое public bool wallchops будет установлено в true, если Группа регулярных выражений <wallchops> возвращается сама.
  • Мой public string chantypes будет установлен в результате регулярных выражений группы <chantypes>

У меня возникли проблемы по монтажу строку поиска регулярных выражений, который ищет и соответствует поле и значение, в ситуациях, что поле не может существовать, и поля могут быть в совершенно ином порядке.

Надеюсь, я проясню это и заполнил все пробелы, которые я забыл.

ответ

0

Друг помог мне с этим, наконец, и мы работали, как успешно соответствовать моим выше строки, погода имеет поле или нет, и независимо от того, что заказ может быть.

(?:(?:SILENCE=(?<silence>\d+)\s?)|(?:MODES=(?<modes>\d+)\s?)|(?:CHANTYPES=(?<chantypes>\S+)\s?)|(?:PREFIX=(?<prefix>\S+)\s?)|(?:MAXTARGETS=(?<maxtargets>\d+)\s?)|(?:WATCH=(?<watch>\d+)\s?)|(?<wallchops>WALLCHOPS)|(?:NETWORK=(?<network>\w+)\s?)|(?:CASEMAPPING=(?<casemapping>\w+)\s?)|(?:CHANMODES=(?<chanmodes>\S+)\s?)|(?:EXTBAN=(?<extban>\S+)\s?)|(?:ELIST=(?<elist>\w+)\s?)|(?:WATCHOPTS=(?<watchopts>\S+)\s?)\s?) 

Да, я понимаю, что это огромная строка поиска Regex Search, и она вернет строки как группы, которые я хотел. Я также понимаю, что это не лучшая идея на практике. Эта поисковая строка будет расти до огромного размера и может, и, вероятно, создаст огромное количество накладных расходов и потратит время на процессорное время для выполнения.

SJ, Я благодарю вас за ваши отзывы, я поместил ваш предлагаемый код и применил его таким образом, с некоторыми незначительными изменениями, конечно.

0

в ситуациях, когда поле может не существовать, и поля могут находиться в совершенно ином порядке.

Я думал, что запись REGEX в вышеупомянутый случай не является лучшей практикой. Вместо этого вы можете использовать простые строковые методы для достижения своей цели.

class IrcParser 
{ 
    private string input; 

    public IrcParser(string input) 
    { 
     this.input = input; 
    } 

    public Irc GetResult() 
    { 
     Irc irc = new Irc(); 
     string[] result = input.Split(); 
     for (int i = 0; i < result.Length; i++) 
     { 
      string[] FieldValue = result[i].Split('='); 
      switch (FieldValue[0]) 
      { 
       case "MAXTARGETS": 
        irc.maxTargets = Convert.ToInt32(FieldValue[1]); 
        break; 
       case "WALLCHOPS": 
        irc.wallChops = true; 
        break; 
       case "CHANTYPES": 
        irc.chanTypes = FieldValue[1]; 
        break; 
      } 
     } 
     return irc; 
    } 

    public Irc GetResultByRegex() 
    { 
     Irc irc = new Irc(); 
     MatchMaxTargets(ref irc.maxTargets); 
     MatchWallChops(ref irc.wallChops); 
     MatchChanTypes(ref irc.chanTypes); 
     return irc; 
    } 

    private void MatchMaxTargets(ref int maxTargets) 
    { 
     Regex regex = new Regex(@"(?<=MAXTARGETS=)(\d+)"); 
     Match m = regex.Match(input); 
     if (m.Success){ 
      maxTargets = Convert.ToInt32(m.Groups[1].Value); 
     } 
    } 

    private void MatchWallChops(ref bool wallChops) 
    { 
     if (Regex.IsMatch(input, "WALLCHOPS")) 
     { 
      wallChops = true; 
     } 
    } 

    private void MatchChanTypes(ref string chanTypes) 
    { 
     Regex regex = new Regex(@"(?<=CHANTYPES=)(.*?)(?=\s)"); 
     Match m = regex.Match(input); 
     if (m.Success) 
     { 
      chanTypes = m.Groups[1].Value; 
     } 
    } 

} 

class Irc 
{ 
    public int maxTargets; 
    public bool wallChops; 
    public string chanTypes; 
} 

Обновлено: Я добавил методы для выполнения матча Regex на отдельных значений полей. Если мы напишем одну строку REGEX, порядок результатов группы изменится в зависимости от наличия полей. (В этой ситуации вы не можете присвоить значение группы соответствующим полям.)

Надеюсь, это поможет вам.
--SJ

+0

Хотя я согласен с тем, что есть, вероятно, гораздо лучшие способы сделать это, однако я ищу строку регулярных выражений, чтобы вернуть это. Я пытаюсь изучить regex и почему это было бы или не было бы лучшей практикой для того, что я пытаюсь выполнить. Я хочу сделать свои собственные ошибки с кодом и учиться у них и улучшить результат в конце. Я непременно возьму ваши струнные методы и увижу, что я могу сделать в этом отношении. Но, в конечном счете, мне нужно Regex для моей проблемы. – Xylex

+0

Мы не можем написать шаблон регулярного выражения в вашем случае. Becasue, ваши значения поля могут или мат не быть представлены в заданной строке. Я обновил свой ответ. –