【问题标题】:regex capture lines before certain keywords that may or may not be present正则表达式在某些可能存在或不存在的关键字之前捕获行
【发布时间】:2017-07-06 15:26:14
【问题描述】:
Changeset: 8675309
User: DOMAIN\JohnG
Date: 01/21/2004 21:03:45
Comment:  This check-in fixes issues in several features.  I also refactored some items in buf.c into a new file named bif.c because buf.c was too hard to parse.
Items:
   $/baz/proj/bif.c           Added
   $/baz/proj/buf.c          Modified, Renamed
Work Items:
   34527     The "Access Denied" message is not descriptive enough.
   35628     The UI flickers when I press the '8', 'y', 'Ctrl', and 'End' buttons at the same time.
Check-in Notes:
   Code Reviewer:  ShellM
   Performance Reviewer: ShellM
   Security Reviewer: ShellM

我想捕获项目下的两行。但是有时工作项可能会丢失,因此签入说明:将是我停止的地方,然后有时 BOTH 会丢失,因此我需要在字符串的末尾停止。

(?s)(?<=Items:).*(?(?=Work Items:)|(?=Check-in Notes:))

这就是我所拥有的,它记录了所有错误的签到记录。

【问题讨论】:

    标签: c# .net regex string


    【解决方案1】:
    ([\s\S]*\nItems:\n)([\s\S]*?)(\nWork Items:\n[\s\S]*)?\z
    

    这似乎有效。您的项目应放在第 2 组中。

    1. ([\s\S]*\nItems:\n) 这告诉正则表达式以“Items:”开头
    2. ([\s\S]*?) 这意味着带字符,但尽可能少(非贪婪)
    3. (\nWork Items:\n[\s\S]*)?\z 这告诉正则表达式用“工作项”填充第三组,如果可能的话。

    这使您的第二组与任一

    • 从“项目:”到 EOF 的所有内容,或
    • 从“项目:”到“工作项目:”的所有内容(独家)

    关键点是第二组(您的项目)不贪婪,第三组可选。这意味着它将始终尝试匹配第三组,但会退回以获取剩余的所有内容。

    编辑:

    在 .Net 中尝试此操作后,上面的正则表达式不起作用。但是经过一些小的调整(比如允许 Win 和 *nix 风格的行尾),它就起作用了。

    var pattern = @"((\n|\r|\r\n)Items:(\n|\r|\r\n))(?<Items>[\s\S]*?)((\n |\r |\r\n)Work Items:(\n |\r |\r\n)[\s\S]*)?\z";
    var regex = new Regex(pattern);
    
    var match = regex.Match(YOUR_FILE_HERE);
    var items = match.Groups["Items"].Value;
    

    【讨论】:

    • Work Items: is not present 但 Check-in Notes 的时间怎么样
    • 在我的测试中它有效。这就是为什么第三组是可选的。
    • 我在不同的网站上进行了测试。但是这个版本对我有用regex101.com/r/B0naal/5(我更新了答案)
    • 我确实在 .Net 中对此进行了测试。我不得不稍微调整一下正则表达式,但现在它适用于尾随工作项,而没有。将更新我的答案。
    • 我刚刚复制了您的代码并将其粘贴到一个 .net 应用程序中,它会捕获 WorkItems 和 Check-in Notes 以及 Items
    【解决方案2】:

    试试下面哪个是测试过的

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;
    using System.Text.RegularExpressions;
    
    namespace ConsoleApplication64
    {
        class Program
        {
            const string FILENAME = @"c:\temp\test.txt";
            static List<string> sections = null;
            public enum State
            {
                NONE = -1,
                CHANGESET = 0,
                USER,
                DATE,
                COMMENT,
                ITEMS,
                WORK_ITEMS,
                CHECK_IN_NOTES
            }
    
            static void Main(string[] args)
            {
                sections = new List<string>() { "Changeset", "User", "Date", "Comment", "Items", "Work Items", "Check-In Notes" }; 
                string pattern = "^(?'section'[^:]+)";
                string inputLine = "";
                StreamReader reader = new StreamReader(FILENAME);
                State state = State.NONE; 
                while ((inputLine = reader.ReadLine()) != null)
                {
                    inputLine = inputLine.Trim();
                    Match match = Regex.Match(inputLine, pattern);
                    if (match.Success)
                    {
                        int index = sections.IndexOf(match.Groups["section"].Value);
                        if(index >= 0) state = (State)index;
                    }
    
                    switch(state)
                    {
                        case State.COMMENT :
                            Console.WriteLine(inputLine);
                            break;
                        case State.ITEMS :
                            Console.WriteLine(inputLine);
                            break;
                    }
    
                }
                Console.ReadLine();
            }
        }
    
    }
    

    【讨论】:

    • 这是迄今为止效果最好的,但是,如果他们的评论消息中有“项目:”,那么也会给我该输出
    猜你喜欢
    • 1970-01-01
    • 2017-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多