【问题标题】:Force parsing optional groups强制解析可选组
【发布时间】:2017-03-16 18:17:21
【问题描述】:

我正在尝试制作一个从报告文件中提取数据的正则表达式字符串。棘手的部分是我需要这个单一的正则表达式字符串来匹配多种报告文件内容格式。即使找不到某些可选组,我也希望正则表达式始终匹配。

获取以下报告文件内容(注意:#2 缺少“val2”部分。):

  • 文件 #1:“-val1-test-val2-result-val3-done-
    • 预期结果:
      • Val1 组:测试
      • Val2 组:结果
      • Val3 组:完成
  • 文件 #2:“-val1-test-val3-done-
    • 预期结果:
      • Val1 组:测试
      • Val2 组:(空)
      • Val3 组:完成

我尝试了以下正则表达式字符串:

Regex #1(Normal): "-val1-(?<val1>.+?)-val2-(?<val2>.+?)-val3-(?<val3>.+?)-"

问题:文件 #1 工作正常,但在文件 #2 上,正则表达式不匹配,因此我没有任何组值。

Regex #2(Non greedy)): "-val1-(?<val1>.+?)(-val2-(?<val2>.+?))?-val3-(?<val3>.+?)-"
Regex #3(Boolean OR): "-val1-(?<val1>.+?)(-val2-(?<val2>.+?)|(.*?))-val3-(?<val3>.+?)-"
Regex #4(Conditionnal): "-val1-(?<val1>.+?)(?(-val2-(?<val2>.+?))|(.+?))-val3-(?<val3>.+?)-"
Regex #5(Conditionnal): "-val1-(?<val1>.+?)(?(-val2-(?<val2>.+?))(-val2-(?<val2>.+?)))-val3-(?<val3>.+?)-"
Regex #6(Conditionnal): "-val1-(?<val1>.+?)(?(-val2-(?<val2>.+?))(-val2-(?<val2>.+?))|(.+?))-val3-(?<val3>.+?)-"

问题:文件 #2 按预期工作,但文件 #1 的 val2 组始终为空。

结论:行为似乎是,即使存在可选组,正则表达式也会优先考虑空组值而不是当前值。有没有办法在可选组存在时强制获取它们的值,并且只在它们不存在时返回(空)?

注意:我使用的是最新的 .NET 框架,代码将移植到 Java(Android)。我试图避免使用多个操作来解决性能和带宽问题。

有人可以帮我解决这个问题吗?

【问题讨论】:

  • 您认为将第三个值设为可选对您来说也是一种有效的方法吗?看看-val1-(?&lt;val1&gt;.+?)(-val2-(?&lt;val2&gt;.+?))?(-val3-(?&lt;val3&gt;.+?))?-
  • 在 C# 中,在我运行的测试程序中,Regex #5 适用于 file1 和 file2。这不是你得到的吗?
  • 原来我的简化示例不够现实。这是一个更好的(基于html内容提取):regex101.com/r/jY4jK1/2;我将最后 3 个组设置为可选,结果是它们没有被提取,知道如何让它工作吗?
  • 您要求正则表达式引擎关心匹配的数据,但它没有足够的信息知道它需要关心。您几乎肯定需要切换到使用 HTML 解析,然后可能将正则表达式与文档树查询结合使用。
  • 我试图在一个进程中一次提取所有信息,但我认为 XPaths 可能更灵活、更安全。让我们希望使用这种技术逐个提取信息不会拖累性能! :-) 感谢您的帮助!

标签: regex optional regex-group


【解决方案1】:

如果我们做一些假设是可能的:

  1. 值可能会丢失,但它们的顺序始终相同
  2. 第一个值始终存在
  3. 在我们要查找的部分前后有一个分隔符

 

-val1-([^-]+)(?:-val2-([^-]+)|)(?:-val3-([^-]+)|)-

https://regex101.com/r/yY6vF9/1

【讨论】:

  • 嗯...嗯,我的例子有点太简单了...你能看看这个吗? regex101.com/r/mI5uI0/1 。前 2 个组将始终存在,所有组的顺序相同,如您所见,有一些 html 代码可用作分隔符。现在的问题是,如果“Time1”组不存在(我在示例中添加了“不存在”),则整个正则表达式不再匹配。你能告诉我如何让你的解决方案适应这种情况吗?
  • 原理相同regex101.com/r/mI5uI0/2虽然这个正则表达式不是100%保存,但是html解析器会更好。这里 time1 和 time2 是可选的,并且必须保留顺序。
  • 谢谢。我想我可以使用 Html Parsing(使用 XPaths);我希望性能不会大幅下降,因为我将在同一源字符串上一一提取信息。 :-)
  • @DonMadrino 这是个好主意。对正则表达式的一项改进是将 ' 和 " 替换为 ['"] 这样您就可以同时使用它们或代替空格来接受任意数量的空格等,但它永远不会 100% 保存。感谢您的接受。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-16
相关资源
最近更新 更多