如何提取括号(圆括号)之间的文本?

时间:2008-12-18 16:32:27

标签: c# .net regex

我有一个字符串User name (sales),我想在括号之间提取文本,我该怎么做?

我怀疑是子字符串,但我无法弄清楚如何阅读直到结束括号,文字的长度会有所不同。

18 个答案:

答案 0 :(得分:408)

一种非常简单的方法是使用正则表达式:

Regex.Match("User name (sales)", @"\(([^)]*)\)").Groups[1].Value

作为对(非常有趣)评论的回应,这里有相同的正则表达式并有一些解释:

\(             # Escaped parenthesis, means "starts with a '(' character"
    (          # Parentheses in a regex mean "put (capture) the stuff 
               #     in between into the Groups array" 
       [^)]    # Any character that is not a ')' character
       *       # Zero or more occurrences of the aforementioned "non ')' char"
    )          # Close the capturing group
\)             # "Ends with a ')' character"

答案 1 :(得分:398)

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

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

答案 2 :(得分:92)

假设你只有一对括号。

string s = "User name (sales)";
int start = s.IndexOf("(") + 1;
int end = s.IndexOf(")", start);
string result = s.Substring(start, end - start);

答案 3 :(得分:24)

使用此功能:

public string GetSubstringByString(string a, string b, string c)
    {
        return c.Substring((c.IndexOf(a) + a.Length), (c.IndexOf(b) - c.IndexOf(a) - a.Length));
    }

以下是用法:

GetSubstringByString("(", ")", "User name (sales)")

,输出为:

sales

答案 4 :(得分:14)

正则表达式可能是最好的工具。如果您不熟悉它们,我建议您安装Expresso - 一个很棒的小正则表达式工具。

类似的东西:

Regex regex = new Regex("\\((?<TextInsideBrackets>\\w+)\\)");
string incomingValue = "Username (sales)";
string insideBrackets = null;
Match match = regex.Match(incomingValue);
if(match.Success)
{
    insideBrackets = match.Groups["TextInsideBrackets"].Value;
}

答案 5 :(得分:13)

string input = "User name (sales)";

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

答案 6 :(得分:13)

正则表达式可能吗?我认为这会奏效......

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

答案 7 :(得分:6)

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;
}

答案 8 :(得分:4)

使用正则表达式:

string test = "(test)"; 
string word = Regex.Match(test, @"\((\w+)\)").Groups[1].Value;
Console.WriteLine(word);

答案 9 :(得分:2)

input.Remove(input.IndexOf(')')).Substring(input.IndexOf('(') + 1);

答案 10 :(得分:2)

我认为regex方法更优越,但如果您想使用简陋的substring

string input= "my name is (Jayne C)";
int start = input.IndexOf("(");
int stop = input.IndexOf(")");
string output = input.Substring(start+1, stop - start - 1);

string input = "my name is (Jayne C)";
string output  = input.Substring(input.IndexOf("(") +1, input.IndexOf(")")- input.IndexOf("(")- 1);

答案 11 :(得分:1)

我发现正则表达式非常有用但很难编写。所以,我做了一些研究,发现这个tool使得编写它们变得如此简单。

不要回避他们,因为语法难以理解。它们可以如此强大。

答案 12 :(得分:1)

int start = input.IndexOf("(") + 1;
int length = input.IndexOf(")") - start;
output = input.Substring(start, length);

答案 13 :(得分:0)

这是一个通用的可读函数,可以避免使用正则表达式:

// 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)", "(", ")");

答案 14 :(得分:0)

当我在寻找一个非常类似的实现方案时,我遇到了这个问题。

以下是我实际代码的摘录。从第一个char(索引0)开始子串。

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

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

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

答案 15 :(得分:0)

此代码比这里的大多数解决方案(如果不是全部)快,打包为String extension method,它不支持递归嵌套:

public static string GetNestedString(this string str, char start, char end)
{
    int s = -1;
    int i = -1;
    while (++i < str.Length)
        if (str[i] == start)
        {
            s = i;
            break;
        }
    int e = -1;
    while(++i < str.Length)
        if (str[i] == end)
        {
            e = i;
            break;
        }
    if (e > s)
        return str.Substring(s + 1, e - s - 1);
    return null;
}

这个更长更慢,但它更好地处理递归嵌套:

public static string GetNestedString(this string str, char start, char end)
{
    int s = -1;
    int i = -1;
    while (++i < str.Length)
        if (str[i] == start)
        {
            s = i;
            break;
        }
    int e = -1;
    int depth = 0;
    while (++i < str.Length)
        if (str[i] == end)
        {
            e = i;
            if (depth == 0)
                break;
            else
                --depth;
        }
        else if (str[i] == start)
            ++depth;
    if (e > s)
        return str.Substring(s + 1, e - s - 1);
    return null;
}

答案 16 :(得分:0)

与@Gustavo Baiocchi Costa非常相似,但正在使用另一个中间 project_list unique_projects frequence projectgroup Banana {3, 5} 2 2 New {2} 1 2 The fantastic {1, 4} 2 1 计算偏移量。

Substring

答案 17 :(得分:0)

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