正则表达式与字典键匹配

时间:2014-06-24 05:18:07

标签: c# regex

我正在扩展之前被问到的question

在我解释之前,这是我的C#代码:

static Dictionary<string, string> phenom = new Dictionary<string, string> 
{
    {"-", "Light"},
    {"\\+", "Heavy"},
    {"\bVC\b","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"}
};

public static string Process(String metar)
{
    metar = Regex.Replace(metar, "(?<=A[0-9]{4}).*", "");
    StringBuilder _string = new StringBuilder();

    var results = from result in phenom
                  where Regex.Match(metar, result.Key, RegexOptions.Singleline).Success
                  select result;

    foreach (var result in results)
    {
        if (result.Key == "DZ" || result.Key == "RA" || result.Key == "SN" || result.Key == "SG" || result.Key == "PL")
        {
            switch (result.Key)
            {
                case "+":
                    _string.Append("Heavy ");
                    break;
                case "-":
                    _string.Append("Light");
                    break;
                case "VC":
                    _string.Append("In the Vicinity ");
                    break;
                default:
                    break;
            }
        }

        _string.AppendFormat("{0} ", result.Value);
    }

    return _string.ToString();
}

基本上,此代码解析机场METAR天气报告中的天气现象。以下面的METAR为例:

  

KAMA 230623Z AUTO 05016KT 7SM + TSRAGR FEW070 BKN090 OVC110 16/14 A3001   RMK AO2 PK WND 06026/0601 LTG DSNT E-SW RAB04 TSB02E17 P0005 T01560144

注意+ TSRAGR ......这是我想要关注的部分。我目前的代码工作得很好......但并不接近我真正想要的。它吐出了这个:“雷雨雷雨”。

实际解码略有不同。参考this manual(见第5页)。

强度指标(+和 - )总是在第一次降水之前出现。在上面的METAR中,它将是RA。因此,理想情况下应该吐出“雷雨大雨”。但事实并非如此。还有一些时候这种现象并不那么激烈......有时它可能只是-RA,在这种情况下应该只返回“小雨”。

另外需要注意的是,正如我引用的手册所说,强度标识符没有用IC,GR,GS或UP降水类型编码,这解释了我在追加强度之前检查键值的尝试,但是失败了。

如果有人能指出我如何将强度标识符附加到正确的位置,我会非常感激。

TL; DR ...基本上,我有一些代码逻辑来决定在字典列表中的特定项目之前放置前缀的位置。

1 个答案:

答案 0 :(得分:0)

考虑到你的代码结构,我建议你预先解析你的输入字符串,将强度指示符“移动”到他们不修改的术语之后,这样的话就会按照最有意义的顺序出现。

然后,我可能会考虑在你的词典中添加几个键来覆盖每种类型降水的+/-版本,它们可以有一个强度指示器,这样你的整体代码就会简化。