C#: String inside Last brackets() of a string 字符串

C#: String inside Last brackets() of a string

在我的一项任务中,我必须在 Bug 状态的最后一组括号内找到 Bug 的 ID。我列出了一些示例错误状态。

错误状态(字符串)看起来像,

Case 1: Bug A is resolved (XID: X015)
Case 2: Bug B is resolved (ZID: X016)
Case 3: Bug C is resolved (Data issue) (SID: X017)

对于案例#1 和#2,我编码类似,找到 ( 和 ) 的第一次出现,并计算括号内的值。

var start = value.IndexOf("(", StringComparison.Ordinal) + 1;
var end = value.IndexOf(")", start, StringComparison.Ordinal);
var BugID = value.Substring(start, end - start);

但在案例#3 中,有两组括号,第一个包含有关错误的摘要,下一个是实际的错误 ID,我需要提取错误 ID。 我必须编写这样的代码,

var start = value.IndexOf(last "(");    //index of last (
var end = value.IndexOf(last ")");  //index of last )
var BugID = value.Substring(start, end - start);

任何建议都会有所帮助!

正则表达式是你的朋友。 Regexp.Matches() 方法将查找给定模式的所有匹配项:

var text = @"Case 1: Bug A is resolved (XID: X015)
Case 2: Bug B is resolved (ZID: X016)
Case 3: Bug C is resolved (Data issue) (SID: X017)";

// Instantiate the regular expression object.
Regex r = new Regex(@"\([^)]*\)", RegexOptions.Multiline);

// Match the regular expression pattern against a text string.
var matches = r.Matches(text);
if(matches.Count > 0)
{
     var last_match = matches[matches.Count - 1];
     Console.WriteLine(last_match.Groups[0].Value);
}

这里有一些可以提取 ID 号的工作代码。它包括 X,假设您需要它。

var lines = new[]
{
    @"Case 1: Bug A is resolved (ID: X015)",
    "Case 2: Bug B is resolved (ID: X016)",
    "Case 3: Bug C is resolved (Data issue) (ID: X017)"
};

foreach(var line in lines)
{

    Regex regex = new Regex(@"(?<=[(]ID:\s)X\d*(?=[)])");

    Match match = regex.Match(line);

    if(match.Success)
    {
        Console.WriteLine(match.Value);
    }
}

Console.ReadLine();

如果您想玩正则表达式,可以使用以下工具:

https://regex101.com/

像这样:

  String source = "Some (123) test (valid value) with ugly -> ( <- tricks";
  String result = null; // what if source doesn´t have brackets?

  int pClose = source.LastIndexOf(')');

  if (pClose >= 0) {
    int pOpen = source.LastIndexOf('(', pClose);

    if (pOpen >= 0)
      result = source.Substring(pOpen + 1, pClose - pOpen - 1);
  }

  ...
  // "valid value"
  Console.Write(result);

试试 LastIndexOf(...) 字符串方法。

var start = value.LastIndexOf(" (") + 1;
var strings = new List<string>
{
    "Case 1: Bug A is resolved (XID: X015)",
    "Case 2: Bug B is resolved (ZID: X016)",
    "Case 3: Bug C is resolved (Data issue) (SID: X017)"
};

foreach (var s in strings)
{
    var result = s.Substring(s.LastIndexOf('('));

    System.Console.WriteLine(result.Trim('(', ')'));
}

returns:

XID: X015

ZID: X016

SID:X017

编辑:使用 Trim() 去掉括号!

有了Regexp,你可以这样写(用LINQPad测试过):

void Main()
{
    string a = "Bug A is resolved (XID: X015)";
    string b = "Bug B is resolved (ZID: X016)";
    string c = "Bug C is resolved (Data issue) (SID: X017)";

    var regex = new System.Text.RegularExpressions.Regex(@"(\([^(]*\))$");

    Console.WriteLine(string.Format("a: {0}", regex.IsMatch(a) ? "YES" : "NO"));
    Console.WriteLine(string.Format("b: {0}", regex.IsMatch(b) ? "YES" : "NO"));
    Console.WriteLine(string.Format("c: {0}", regex.IsMatch(c) ? "YES" : "NO"));

    var aMatches = regex.Matches(a);
    var bMatches = regex.Matches(b);
    var cMatches = regex.Matches(c);

    Console.WriteLine(string.Format("a: {0}", aMatches[aMatches.Count - 1]));
    Console.WriteLine(string.Format("b: {0}", bMatches[bMatches.Count - 1]));
    Console.WriteLine(string.Format("c: {0}", cMatches[cMatches.Count - 1]));
}

这个怎么样

using System.IO;
using System;

class Program
{
    static void Main()
    {
        var str = "Bug C is resolved (Data issue) (SID: X017)";
        var index = str.IndexOf("ID: ");
        Console.WriteLine(index);
        // + 4 is the length of the string "ID: "
        // so again we are subtracting it back along with -1 to remove the last paranthesis
        str = str.Substring(index + 4, str.Length - index - 4 - 1);
        Console.WriteLine(str);
    }
}