#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.