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

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


当前回答

我最近一直在使用和滥用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 "";
}

其他回答

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

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

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

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

 output = input.Substring(0, input.IndexOf(separator)); 
string input = "User name (sales)";

string output = input.Substring(input.IndexOf('(') + 1, input.IndexOf(')') - input.IndexOf('(') - 1);

非常类似于@Gustavo Baiocchi Costa,但偏移量是用另一个中间子字符串计算的。

int innerTextStart = input.IndexOf("(") + 1;
int innerTextLength = input.Substring(start).IndexOf(")");
string output = input.Substring(innerTextStart, innerTextLength);
using System;
using System.Text.RegularExpressions;

private IEnumerable<string> GetSubStrings(string input, string start, string end)
{
    Regex r = new Regex(Regex.Escape(start) +`"(.*?)"`  + Regex.Escape(end));
    MatchCollection matches = r.Matches(input);
    foreach (Match match in matches)
    yield return match.Groups[1].Value;
}
input.Remove(input.IndexOf(')')).Substring(input.IndexOf('(') + 1);