正则表达式:处理参数

时间:2017-06-13 19:16:43

标签: .net regex

我想解析一些具有

形式的文本
(<paramID><paramValue>)*(LastValue)*

其中paramID是参数的ID,paramValue几乎是任何不包含潜在paramID的东西(所以我们可以毫不含糊地解析它)。

需要注意的主要事项是:

  1. 第一个paramID可以是可选的。
  2. paramValues可以使用分组。分组中的任何内容都被视为一个标记,即使是似乎是paramID的标记。
  3. 每个paramValue都被贪婪地解析,除了最​​后一个,它被懒惰地解析。 (我意识到这使得相同参数的不同排序有不同的解释,但解释本身总是很好地定义并且易于理解)
  4. paramID = "\s-[^\s\[\(\{\\""]+" paramValue =基本上是paramID之间的内容。由于这可能包含类似于paramID的内容,但由于它们位于&#34;组&#34;内,因此需要忽略它们。

    如,

    First Param Value -p1 Second Param Value -p2[Third-Param-Value] -X "-Fourth -Param -Value" -pl LastParamValue Last Value
    
    应该以明显的方式解析

1 个答案:

答案 0 :(得分:1)

我建议将表达式标记为如下:

  • 括号内的组。
    • 使用balanced groupsvoid tmrRepeatedScan_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { try { lock (thisLock) { var detectedTags = serialPort.Scan(true, false, true, false); foreach (var tag in detectedTags) { bool tagFound = false; string TID = Regex.Replace(Conversions.ByteToHexadecimal(tag.GetTagId()), "(.{2})(?!$)", "$0-"); string EPC = Regex.Replace(Conversions.ByteToHexadecimal(tag.GetEpc()), "(.{2})(?!$)", "$0-"); foreach (DataGridViewRow row in dgvTags.Rows) { if (row.Cells[0].Value.ToString().Equals(TID)) { row.DefaultCellStyle.BackColor = Color.LightGreen; tagFound = true; break; } } bool isNewTag = !tagsReaded.Contains(TID); if (!tagFound && isNewTag ) { dgvTags.BeginInvoke(new InvokeDelegate(() => AddRow(TID, EPC))); } if (newTag) { tagsReaded.Add(TID); } } } foreach (DataGridViewRow row in dgvTags.Rows) { if (!tagsReaded.Contains(row.Cells[0].Value.ToString())) { row.DefaultCellStyle.BackColor = Color.White; } } } catch (Exception ex) { foreach (DataGridViewRow row in dgvTags.Rows) { row.DefaultCellStyle.BackColor = Color.White; } } } 可能会(?>(?'o'\[)[^][]*)+(?>[^][]*(?'-o'\]))+。这允许组嵌套。
    • 可能会为[...]{...}群组生成类似的表达
  • 引号中的组(可能在其中包含转义引号)
  • 以破折号开头的参数名称以空格
  • 开头
  • 将部分视为由空格包围的一系列非空格字符。以后这些参数将连接所有参数,但最后一个参数。对于最后一个参数,仅采用第一个值,而其他值则构成最后一个值。

所以tokenizer表达式是:

(...)

Demo

然后我们需要扫描标记并适当地收集参数值对:​​

(?x)
  \s*(?<token> (?>(?'o'\[)[^][]*)+(?>[^][]*(?'-o'\]))+ )\s*  # balanced [...] group
| \s*(?<token> (?>(?'o'\{)[^{}]*)+(?>[^{}]*(?'-o'\}))+ )\s*  # balanced {...} group
| \s*(?<token> (?>(?'o'\()[^()]*)+(?>[^()]*(?'-o'\)))+ )\s*  # balanced (...) group
| \s*(?<token> "(?:\\"|[^"])*" )\s*   # quoted group with possible escaped quotes within
| \s*(?<token> -[^\s"({[]+ )          # parameter name
| (?<token> \s*\S+\s* )               # parameter value part not in group/quotes

演示:https://dotnetfiddle.net/bg1jxp