我在C#控制台应用程序中有一个用于捕获命令的正则表达式。用户可以在同一行中编写多个命令。问题是这些命令不是按照编写顺序捕获的,而是按照正则表达式命名的捕获组的编写顺序捕获的。例如,如果用户键入:
- Q I
下面的正则表达式会先捕获I,然后捕获Q,导致命令执行顺序错误。有可能在正则表达式中修复这个问题吗?^((?<state>I\s?)?()|(?<quit>Q\s?)?()|(?<time>VR (\d{2}\.\d{2}\.\d{4}\. \d{2}\:\d{2}\:\d{2})\s?)?()|(?<connection_type>V (?:PU|PO|OS) (:?S|Z) (\d{2}\.\d{2}\.\d{4}\. \d{2}\:\d{2}\:\d{2}) (\d{2}\.\d{2}\.\d{4}\. \d{2}\:\d{2}\:\d{2})\s?)?()|(?<request_file>UR [0-9a-zA-Z_-]{1,}\.csv\s?)?()|(?<create_reserved_request>ZD [0-9]{1,}\s?)?()|(?<create_request>ZP [0-9]{1,} [0-9]{1,}\s?)?()|(?<ship_channel>F [0-9]{1,} [0-9]{1,}( [Q])?\s?)?()|(?<table_formating>T(( P)?()|( Z)?()|( RB)?\s?){1,3})?()|(?<occupied_connections_by_type>ZA (\d{2}\.\d{2}\.\d{4}\. \d{2}\:\d{2})\s?)?()|(?<print_data>VF(( R)?()|( B)?()|( M)?()|( K)?()|( D)?\s?){1,8})?)*$
编码:
string regexCommands = @"(^((?<status_vezova>I\s?)?()|(?<prekid_rada>Q\s?)?()|(?<vrijeme>VR (\d{2}\.\d{2}\.\d{4}\. \d{2}\:\d{2}\:\d{2})\s?)?()" +
@"|(?<vezovi_po_vrsti>V (?:PU|PO|OS) (:?S|Z) (\d{2}\.\d{2}\.\d{4}\. \d{2}\:\d{2}\:\d{2}) (\d{2}\.\d{2}\.\d{4}\. \d{2}\:\d{2}\:\d{2})\s?)?()|" +
@"(?<datoteka_zahtjeva>UR [0-9a-zA-Z_-]{1,}\.csv\s?)?()|(?<kreiranje_rezerviranog_zahtjev>ZD [0-9]{1,}\s?)?()|" +
@"(?<kreiranje_zahtjeva>ZP [0-9]{1,} [0-9]{1,}\s?)?()|(?<komunikacija_brod_kanal>F [0-9]{1,} [0-9]{1,}( [Q])?\s?)?()|" +
@"(?<format_ispisa_tablica>T(( P)?()|( Z)?()|( RB)?\s?){1,3})?()|(?<zauzeti_vezovi_prema_vrsti>ZA (\d{2}\.\d{2}\.\d{4}\. \d{2}\:\d{2})\s?)?()|(?<ispis_podataka>VF(( R)?()|( B)?()|( M)?()|( K)?()|( D)?\s?){1,8})?)*$)";
string commands = Console.ReadLine();
Regex regex = new Regex(regexCommands);
Match match = regex.Match(commands);
if (!regex.IsMatch(naredba!))
{
throw new Exception();
}
List<KeyValuePair<string, string>> listRegexGroupsAndValues = new List<KeyValuePair<string, string>>();
GroupCollection groups = match.Groups;
//insert all regex named groups and values in list
foreach (string groupName in regex.GetGroupNames())
{
if (groupName.Length > 2)
listRegexGroupsAndValues.Add(new KeyValuePair<string, string>(groupName, groups[groupName].Value));
}
//print
foreach (KeyValuePair<string, string> pair in listRegexGroupsAndValues)
{
Console.WriteLine(pair.Key + " " + pair.Value);
}
这样我就可以把用户写的所有命令都放在一个键值对列表中,然后我就可以遍历这个列表,并使用工厂方法执行每个命令。
2条答案
按热度按时间liwlm1x91#
您可以依撷取的“索引”特性来排序撷取。请先从相关群组收集所有相符项目,然后再依撷取的“索引”来排序。
输出为:
qco9c6ql2#
当Regex返回匹配项时,您可以检查the
Index
property in the underlyingCapture
class以检查特定捕获/组在原始字符串中的哪个位置匹配。如果您是针对单个命令流进行匹配,则如果您按此
Index
对生成的捕获/组进行排序,则它应按键入的顺序给予结果。应该可以这样做:
这并不意味着依赖Regex是解析这类复杂命令的最佳方法,但如果您想继续使用单个
Regex
,这可能会起作用。