【问题标题】:RegEx for parsing repeated groups用于解析重复组的正则表达式
【发布时间】:2019-10-18 10:30:57
【问题描述】:

源字符串包含这样的标签:

>>>tagA
contents 1
<<<tagA
...
>>>tagB
contents 2
<<<tagB
...

我需要提取其中的标签名称和内容。这就是我所拥有的,但仍然无法正常工作:

(?<=(>>>(?<tagName>.+)$))(?<contents2>.*?)(?=(<<<.+)$)

results 匹配了两个匹配项,但第二个匹配项中的 tagName 捕获了多行:

tagA 
contents 1 
<<<tagA

我做错了什么?

【问题讨论】:

  • 如果您(似乎)只关心捕获的命名组,为什么还要使用后视/前瞻零长度断言?我是否可能遗漏了您的用例?为什么不“简单地”&gt;&gt;&gt;(?&lt;tagName&gt;[^\n\r]+)[\n\r]+(?&lt;contents&gt;.*?)&lt;&lt;&lt;(需要单行匹配选项);-)
  • 我明白一件事:RegEx 在你完全学会之前真的很痛苦 :)

标签: c# .net regex regex-lookarounds regex-group


【解决方案1】:

你可以使用

>>>(?<tagName>.+?)[\r\n]+(?s:(?<contents>.*?))<<<

regex demo

详情

  • &gt;&gt;&gt; - &gt;&gt;&gt; 子字符串
  • (?&lt;tagName&gt;.+?) - 组“tagName”:尽可能少的任何 1+ 个字符
  • [\r\n]+ - 一个或多个 CR 或 LF 符号
  • (?s:(?&lt;contents&gt;.*?)) - 组“内容”:匹配任何 0+ 字符的内联修饰符组,但尽可能少
  • &lt;&lt;&lt; - &lt;&lt;&lt; 子字符串。

在 C# 中:

var matches = Regex.Matches(s, @">>>(?<tagName>.+?)[\r\n]+(?s:(?<contents>.*?))<<<");

C# demo

var s = ">>>tagA\ncontents 1\n<<<tagA\n...\n>>>tagB\ncontents 2\n<<<tagB\n...";
var matches = Regex.Matches(s, @">>>(?<tagName>.+?)[\r\n]+(?s:(?<contents>.*?))<<<");
foreach (Match m in matches) {
    Console.WriteLine(m.Groups["tagName"].Value);
    Console.WriteLine(m.Groups["contents"].Value);
}

输出:

tagA
contents 1

tagB
contents 2

【讨论】:

    【解决方案2】:

    在这里,我们可能会从一个以&gt;&gt;&gt;&lt;&lt;&lt; 为界的简单表达式开始,可能类似于:

    >>>(.+)\s*(.+)\s*<<<.+
    

    我们在这两个捕获组中拥有我们想要的数据:

    (.+)
    

    我们将编写剩下的问题。

    Demo

    测试

    using System;
    using System.Text.RegularExpressions;
    
    public class Example
    {
        public static void Main()
        {
            string pattern = @">>>(.+)\s*(.+)\s*<<<.+";
            string input = @">>>tagA
                contents 1
                <<<tagA
    
                >>>tagB
                contents 2
                <<<tagB
    
                >>>tagC
    
                contents 2
    
    <<<tagC
    ";
            RegexOptions options = RegexOptions.Multiline;
            
            foreach (Match m in Regex.Matches(input, pattern, options))
            {
                Console.WriteLine("'{0}' found at index {1}.", m.Value, m.Index);
            }
        }
    }
    

    正则表达式电路

    jex.im 可视化正则表达式:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-30
      • 1970-01-01
      • 2015-01-29
      • 2015-07-16
      • 2018-04-29
      • 2015-03-13
      相关资源
      最近更新 更多