正则表达式使用字典对查找匹配项
本文关键字:查找 字典 正则表达式 | 更新日期: 2023-09-27 17:53:33
我是c#及其正则表达式功能的新手。基本上,我想使用以下字典并将其与一些正则表达式进行匹配,以查看这样的字符串是否存在于字符串中。
// weather phenomenons
Dictionary<string, object> wxMap = new Dictionary<string, object> {
{"MI", "shallow "},
{"BL", "blowing "},
{"BC", "patches "},
{"SH", "showers "},
{"PR", "partials "},
{"DR", "drifting "},
{"TS", "thunderstorm "},
{"FZ", "freezing "},
{"DZ", "drizzle "},
{"IC", "ice crystals "},
{"UP", "unknown "},
{"RA", "rain "},
{"PL", "ice pellets "},
{"SN", "snow "},
{"GR", "hail "},
{"SG", "snow grains "},
{"GS", "small hail/snow pellets "},
{"BR", "mist "},
{"SA", "sand "},
{"FU", "smoke "},
{"HZ", "haze "},
{"FG", "fog "},
{"VA", "volcanic ash "},
{"PY", "spray "},
{"DU", "widespread dust "},
{"SQ", "squall "},
{"FC", "funnel cloud "},
{"SS", "sand storm "},
{"DS", "dust storm "},
{"PO", "well developed dust/sand swirls "},
{"VC", "vicinity "},
{"RE", "recent "}
};
我想匹配一个METAR字符串,它可能有也可能没有这些现象。
KLAX 260053Z 27012KT 10SM -SN BR BKN017 OVC200 16/11 A2992 RMK AO2 SLP132 T01560111
如果我有以下PHP(从这里取的),但我不确定如何准确地转换它,所以它会从字典中选择正确的现象(我也想注入Heavy/Light/Vicinity字符串,太)。
public $texts=Array('MI'=>'Shallow','PR'=>'Partial','BC'=>'Low drifting','BL'=>'Blowing',
'SH'=>'Showers','TS'=>'Thunderstorm','FZ'=>'Freezing','DZ'=>'Drizzle','RA'=>'Rain','SN'=>'Snow',
'SG'=>'Snow Grains','IC'=>'Ice crystals','PL'=>'Ice pellets','GR'=>'Hail','GS'=>'Small hail',
'UP'=>'Unknown','BR'=>'Mist','FG'=>'Fog','FU'=>'Smoke','VA'=>'Volcanic ash','DU'=>'Widespread dust',
'SA'=>'Sand','HZ'=>'Haze','PY'=>'Spray','PO'=>'Well developed dust / sand whirls','SQ'=>'Squalls',
'FC'=>'Funnel clouds inc tornadoes or waterspouts','SS'=>'Sandstorm','DS'=>'Duststorm');
if(preg_match('#^('+|'-|VC)?('.implode('|',array_keys($this->texts)).')('.implode('|',array_keys($this->texts)).')?$#',$code,$matches))
{
$text=Array();
switch($matches[1]) {
case '+':
$text[]='Heavy';
break;
case '-':
$text[]='Light';
break;
case 'VC':
$text[]='Vicinity';
break;
default:
break;
}
if($matches[2])
$text[]=$this->texts[$matches[2]];
if($matches[3])
$text[]=$this->texts[$matches[3]];
$this->addWeather(implode(' ',$text));
return;
}
基本上,这将解析METAR(使用正则表达式匹配现象部分),例如,包含了KLAX METAR I,它将返回小雪和雾。
如果有人能在正确的道路上帮助我,我将不胜感激。
c#中直接等效的代码是:
class Program
{
static Dictionary<string, object> wxMap = new Dictionary<string, object>
{
{"MI", "shallow "},
{"BL", "blowing "},
{"BC", "patches "},
{"SH", "showers "},
{"PR", "partials "},
{"DR", "drifting "},
{"TS", "thunderstorm "},
{"FZ", "freezing "},
{"DZ", "drizzle "},
{"IC", "ice crystals "},
{"UP", "unknown "},
{"RA", "rain "},
{"PL", "ice pellets "},
{"SN", "snow "},
{"GR", "hail "},
{"SG", "snow grains "},
{"GS", "small hail/snow pellets "},
{"BR", "mist "},
{"SA", "sand "},
{"FU", "smoke "},
{"HZ", "haze "},
{"FG", "fog "},
{"VA", "volcanic ash "},
{"PY", "spray "},
{"DU", "widespread dust "},
{"SQ", "squall "},
{"FC", "funnel cloud "},
{"SS", "sand storm "},
{"DS", "dust storm "},
{"PO", "well developed dust/sand swirls "},
{"VC", "vicinity "},
{"RE", "recent "}
};
static string Process(String metar)
{
string pattern = @"('+|'-|VC)?(" + String.Join("|", wxMap.Keys) + ") (" + String.Join("|", wxMap.Keys) + ")?";
StringBuilder result = new StringBuilder();
Regex r = new Regex(pattern);
Match mc = r.Match(metar);
GroupCollection gc = mc.Groups;
switch(gc[1].Value)
{
case "+":
result.Append("Heavy");
break;
case "-":
result.Append("Light");
break;
case "VC":
result.Append("Vicinity");
break;
default:
break;
}
result.AppendFormat(" {0}", wxMap[gc[2].Value]);
if(gc.Count > 2)
result.AppendFormat("and {0}", wxMap[gc[3].Value]);
return result.ToString();
}
static void Main()
{
string output = Process("KLAX 260053Z 27012KT 10SM -SN BR BKN017 OVC200 16/11 A2992 RMK AO2 SLP132 T01560111");
Console.WriteLine(output);
}
我认为这个问题很适合使用LINQ
.试试这个代码:
var input= "KLAX 260053Z 27012KT 10SM -SN BR BKN017 OVC200 16/11 A2992 RMK AO2 SLP132 T01560111";
var pairs = new Dictionary<string, string>
{
{"+", "Heavy"},
{"-", "Light"},
{"VC", "Vicinity"}
};
var result = input.Split()
.Where(x => wxMap.Keys.Any(x.Contains))
.Select(x =>
{
if (x.Length == 2) return wxMap[x];
if (x.Length == 3)
return pairs[x[0].ToString()] + " " + wxMap[x.Substring(1)];
if (x.Length == 4)
return pairs[x[0].ToString() + x[1]] + " " + wxMap[x.Substring(2)];
return string.Empty;
});
var output = string.Join(" ", result); // Light snow mist
注意:这个答案假设所有后缀(-
, +
和VC
)出现在实际的Key之前。例如,如果您的输入字符串包含SN-
,这将不起作用,并抛出异常。
我的想法与selman22相同,使用条件"levels"的字典:
var levels = new Dictionary<string, object>
{
{ "", "" },
{ "-", "Light" },
{ "+", "Heavy" },
{ "VC", "Vicinity" }
};
您可以使用LINQ查询语法连接您的级别,条件和METAR字符串(在空间上分割):
var conditions
= string.Join("and ", from l in levels.Keys
from w in wxMap.Keys
join m in metar.Split() on string.Concat(l, w) equals m
select string.Concat(levels[l], wxMap[w]));
输出(使用示例字符串):
薄雾和小雪