【问题标题】:Regex Pattern that Looks for a String between two Specified Strings在两个指定字符串之间查找字符串的正则表达式模式
【发布时间】:2013-08-20 20:28:15
【问题描述】:

我有一个文本文件,我从中提取了 C# 中的一行,如下所示:

Date: 8/20/2013 12:00:00 AM Source Path: \\build\PM\11.0.25.9\ Destination Path: C:\Users\Documents\testing\11.0.25.9\etc\ Folder Updated: 11.0.25.9 File Copied: 11052_0_X.pts

提取我需要的变量的最简单方法是创建一个正则表达式模式来查找它。

假设我正在尝试从这行文本中提取源路径。 我将如何创建一个在两个字符串之间查找字符串的模式。比如如何从“Source Path:”和“Destination Path:”之间提取源路径字符串?

到目前为止,我所拥有的是: Regex.Match(line,@"源路径:");

使用http://regexhero.net/tester/ 对此进行测试,显然它所做的只是寻找源路径:到目前为止。我怎么能向前看,直到字符串“目标路径:”?

【问题讨论】:

  • 如果您不确定正则表达式是如何工作的(而且您是),为什么不使用两次调用IndexOf() 和一次调用Substring()

标签: c# regex


【解决方案1】:
string input = @"Date: 8/20/2013 12:00:00 AM Source Path: \\build\PM\11.0.25.9\ Destination Path: C:\Users\Documents\testing\11.0.25.9\etc\ Folder Updated: 11.0.25.9 File Copied: 11052_0_X.pts";
string pattern = @"Source Path:(.+?)Destination Path:";

var src = Regex.Match(input,pattern).Groups[1].Value.Trim();

【讨论】:

    【解决方案2】:

    你可以用这个:

    var path = Regex.Match(line, @"Source Path:\s*(.*)\s*Destination Path:")
                    .Groups[1].Value;
    

    或者这个(使用环视断言):

    var path = Regex.Match(line, @"(?<=Source Path:\s*).*(?=\s*Destination Path:)")
                    .Value;
    

    但是对于这么简单的事情,你并没有真正的正则表达式。这同样适用:

    var startAt = "Source Path:";
    var endAt = "Destination Path:";
    
    var start = line.IndexOf(startAt);
    var end   = line.IndexOf(endAt);
    if (start >= 0 && end >= 0 && (end >= start + startAt.Length))
    {
        var path = line.Substring(start + startAt.Length, 
                                  end - start - startAt.Length).Trim();
    }
    

    【讨论】:

    • 除了 IndexOf/Substring 版本是错误的(返回\\build\PM\11.0.25.9\ Destination在你修复它之前)并且缺少任何错误检查,使其非常错误。这就是为什么你要编写表达意图的代码,而不是编写脆弱的索引操作:)
    • @sehe 这是关于错误检查的一个有效观点,但我不明白你为什么说这比正则表达式更脆弱。它与正则表达式模式一样依赖于输入。
    • 阿赫姆?你第一次弄错了,有魔法常量(不再重复,现在:赞),没有错误检查意味着如果end 是-1,你会得到ERROR] FATAL UNHANDLED EXCEPTION: System.ArgumentOutOfRangeException: Cannot be negative.,但默默地错误如果start11 [原文如此],则结果。那怎么脆的?
    • IOW:它很脆弱,因为它不仅依赖于输入,它还依赖于它包含特定顺序的特定子字符串,并且没有明确定义的故障模式。 正则表达式只会返回.Success==false。此外,正则表达式在单个字符串中表达了在两个文本中捕获(.*?) 的意图。
    • @sehe 是的,我同意错误检查(基于索引的代码旨在作为起点而不是完整的解决方案),并且我同意正则表达式通常是一种更灵活的解决方案。但是当我看到诸如“在这个固定输入和这个固定输入之间找到一个子字符串”之类的问题时,正则表达式只是用一个两个神奇的常量换一个,并在代码中引入了更多潜在的复杂性。根据情况,我可能会在自己的代码中使用正则表达式,但至少应该考虑更简单的解决方案,IMO。
    猜你喜欢
    • 1970-01-01
    • 2012-05-19
    • 2019-05-19
    • 2012-05-27
    • 2017-12-20
    • 1970-01-01
    • 1970-01-01
    • 2020-01-22
    • 1970-01-01
    相关资源
    最近更新 更多