Сопоставление именованных групп регулярных выражений с ключом словаря

#c# #regex

#c# #регулярное выражение

Вопрос:

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

Сама строка является метеометрикой аэропорта (прогноз погоды):

KLAX 050453Z 33003KT 10SM TSRAGR HZ BR FEW010 SCT020 21/17 A3001 RMK AO2 SLP161 T02060172

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

 Regex MetarExpression = new Regex(@"s(?<intensity>[ -VC]{1,2})?(?<descriptor>(MI|PR|BC|DR|BL|SH|TS|FZ))(?<group>(DZ|RA|SN|SG|IC|PL|GR|GS|UP|BR|FG|FU|VA|DU|SA|HZ|PY|PO|SQ|FC|SS|DS)) s");
  

В принципе, мне нужно переписать группы погоды (в этом примере, TSRAGR, HZ и BR) в их соответствующий перевод, который будет «Гроза, сильный дождь, град, дымка, туман»

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

 Match m = MetarExpression.Match(metar);
if (m.Success)
{
    StringBuilder sb = new StringBuilder();

    if(phenom.ContainsKey(m.Groups["descriptor"].Value))
    {
        sb.Append(phenom[m.Groups["descriptor"].Value]);
        sb.Append(", ");
    }

    if (phenom.ContainsKey(m.Groups["intensity"].Value))
    {
        sb.Append(phenom[m.Groups["intensity"].Value]);
        sb.Append(" ");
    }

    foreach (Capture cap in m.Groups["group"].Captures)
    {
        if (phenom.ContainsKey(cap.Value))
        {
            sb.Append(phenom[cap.Value]);
            sb.Append(" ");
        }
    }
    Console.WriteLine(sb);
}
  

Словарь:

   static Dictionary<string, string> phenom = new Dictionary<string, string>
  {
      {"-", "Light"},
      {" ", "Heavy"},
      {"VC","In the Vicinity"},
      // descriptor
      {"MI","Shallow"},
      {"PR","Partial"},
      {"BC","Patches"},
      {"DR","Low Drifting"},
      {"BL","Blowing"},
      {"SH","Showers"},
      {"TS","Thunderstorm"},
      {"FZ","Freezing"},
      // precipitation
      {"DZ","Drizzle"},
      {"RA","Rain"},
      {"SN","Snow"},
      {"SG","Snow Grains"},
      {"IC","Ice Crystals"},
      {"PL","Ice Pellets"},
      {"GR","Hail"},
      {"GS","Small Hail/Snow Pellets"},
      {"UP","Uknown Precipitation"},
      // obscuration
      {"BR","Mist"},
      {"FG","Fog"},
      {"FU","Smoke"},
      {"VA","Volcanic Ash"},
      {"DU","Widespread Dust"},
      {"SA","Sand"},
      {"HZ","Haze"},
      {"PY","Spray"},
      // other
      {"PO","Well-Developed Dust/Sand Whirls"},
      {"SQ","Squalls"},
      {"FC","Funnel Cloud Tornado Waterspout"},
      {"SS","Sandstorm"},
      {"DS","Duststorm"}
  };
  

Проблема, с которой я сталкиваюсь, заключается в том, что он захватывает только первую группу погоды ( TSRAGR), а не две другие.

Есть идеи о том, как это исправить?

Комментарии:

1. фиксируется ли ваше регулярное выражение RA ?

Ответ №1:

Если вы хотите, чтобы были записаны HZ и BR, попробуйте следующее,

 Regex MetarExpression = new Regex(@"s(?<intensity>[ -VC]{1,2})?(?<descriptor>(MI|PR|BC|DR|BL|SH|TS|FZ))(?<group>(DZ|RA|SN|SG|IC|PL|GR|GS|UP|BR|FG|FU|VA|DU|SA|HZ|PY|PO|SQ|FC|SS|DS))s(?<group1>(DZ|RA|SN|SG|IC|PL|GR|GS|UP|BR|FG|FU|VA|DU|SA|HZ|PY|PO|SQ|FC|SS|DS))s(?<group2>(DZ|RA|SN|SG|IC|PL|GR|GS|UP|BR|FG|FU|VA|DU|SA|HZ|PY|PO|SQ|FC|SS|DS))");
  

Поскольку между ними находится пробел, это блокирует захват. Вам нужно указать другие группы для захвата HZ и BR .

ДЕМОНСТРАЦИЯ

Оно будет записываться TSRAGR HZ BR отдельно.

 s(?<intensity>[ -VC]{1,2})?(?<descriptor>(MI|PR|BC|DR|BL|SH|TS|FZ))(?<group>(DZ|RA|SN|SG|IC|PL|GR|GS|UP|BR|FG|FU|VA|DU|SA|HZ|PY|PO|SQ|FC|SS|DS))(?<group1>(DZ|RA|SN|SG|IC|PL|GR|GS|UP|BR|FG|FU|VA|DU|SA|HZ|PY|PO|SQ|FC|SS|DS)) s(?<group2>(DZ|RA|SN|SG|IC|PL|GR|GS|UP|BR|FG|FU|VA|DU|SA|HZ|PY|PO|SQ|FC|SS|DS))s(?<group3>(DZ|RA|SN|SG|IC|PL|GR|GS|UP|BR|FG|FU|VA|DU|SA|HZ|PY|PO|SQ|FC|SS|DS))
  

ДЕМОНСТРАЦИЯ

Комментарии:

1. Почти работает! Единственная проблема, с которой я сталкиваюсь, заключается в том, что если существует менее трех групп погоды. Допустим, что существует только RA BR…it ничего не фиксирует. Обратите внимание, что в отчете METAR может быть максимум три группы погоды (также может не быть ни одной).

2. просто сделайте захваченную группу необязательной.

3. Я сделал группу захвата необязательной, но теперь проблема в том, что если существует только одна группа погоды, после нее требуется два (2) пробела, чтобы она была захвачена. Есть идеи?

4. @Zach Пример был бы лучше.

5. Так, например, если у меня есть этот METAR: KLAX 050553Z 34003KT 7SM -RA HZ FEW010 21/17 A3001 RMK AO2 SLP161 T02110172 10233 20206 51015 он должен фиксировать -RA и HZ … если у меня есть KLAX 050553Z 34003KT 7SM RA FEW010 21/17 A3001 RMK AO2 SLP161 T02110172 10233 20206 51015 , он должен фиксировать RA.