我有一个字符串用户名(销售),我想提取括号之间的文本,我该如何做到这一点?

我怀疑子字符串,但我不知道如何阅读,直到右括号,文本的长度会有所不同。


当前回答

如果你想远离正则表达式,我能想到的最简单的方法是:

string input = "User name (sales)";
string output = input.Split('(', ')')[1];

其他回答

 var input = "12(34)1(12)(14)234";
 var output = "";
 for (int i = 0; i < input.Length; i++)
 {
     if (input[i] == '(')
     {
         var start = i + 1;
         var end = input.IndexOf(')', i + 1);
         output += input.Substring(start, end - start) + ",";
     }
 }

 if (output.Length > 0) // remove last comma
  output = output.Remove(output.Length - 1);

输出:“34,12,14”

我在寻找一个非常相似的实现的解决方案时遇到了这个问题。

下面是我的实际代码片段。从第一个字符(索引0)开始子字符串。

 string separator = "\n";     //line terminator

 string output;
 string input= "HowAreYou?\nLets go there!";

 output = input.Substring(0, input.IndexOf(separator)); 

下面是一个通用的可读函数,避免使用regex:

// Returns the text between 'start' and 'end'.
string ExtractBetween(string text, string start, string end)
{
  int iStart = text.IndexOf(start);
  iStart = (iStart == -1) ? 0 : iStart + start.Length;
  int iEnd = text.LastIndexOf(end);
  if(iEnd == -1)
  {
    iEnd = text.Length;
  }
  int len = iEnd - iStart;

  return text.Substring(iStart, len);
}

要在你的特定例子中调用它,你可以这样做:

string result = ExtractBetween("User name (sales)", "(", ")");

也许是正则表达式?我认为这行得通……

\(([a-z]+?)\)

我最近一直在使用和滥用c# 9,甚至在一些可疑的场景中,我也忍不住要加入span…只是为了好玩,以下是上述答案的变体:

var input = "User name (sales)";
var txtSpan = input.AsSpan();
var startPoint = txtSpan.IndexOf('(') + 1;
var length = txtSpan.LastIndexOf(')') - startPoint;
var output = txtSpan.Slice(startPoint, length);

对于OP的特定场景,它产生正确的输出。 (就我个人而言,我会使用其他人发布的RegEx。在上述解决方案崩溃的情况下,更容易解决更棘手的情况)。

我为自己的项目做了一个更好的版本(作为扩展方法):

//Note: This only captures the first occurrence, but 
//can be easily modified to scan across the text (I'd prefer Slicing a Span)  
public static string ExtractFromBetweenChars(this string txt, char openChar, char closeChar)
{
    ReadOnlySpan<char> span = txt.AsSpan();
    int firstCharPos = span.IndexOf(openChar);
    int lastCharPos = -1;

    if (firstCharPos != -1) 
    { 
        for (int n = firstCharPos + 1; n < span.Length; n++)
        {
            if (span[n] == openChar) firstCharPos = n; //This allows the opening char position to change
            if (span[n] == closeChar) lastCharPos = n;
            if (lastCharPos > firstCharPos) break;
            //This would correctly extract "sales" from this [contrived]
            //example: "just (a (name (sales) )))(test"
        }
        return span.Slice(firstCharPos + 1, lastCharPos - firstCharPos - 1).ToString();
    }
    return "";
}