괄호 (대괄호) 사이에있는 텍스트는 어떻게 추출합니까?


224

문자열이 User name (sales)있고 대괄호 사이에 텍스트를 추출하고 싶습니다. 어떻게해야합니까?

하위 문자열을 의심하지만 닫는 대괄호까지 읽을 수있는 방법을 찾을 수 없습니다. 텍스트 길이가 다릅니다.


2
당신이 시도한 것을 보여주세요. 정규식 사용을 보았습니까?
George Stocker

답변:


445

정규식을 피하고 싶다면 가장 간단한 방법은 다음과 같습니다.

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

91
솔직히 이것은 답변으로 선택되어야합니다.
Pat Lindley

1
input.Split ( "()". ToCharArray ()) [1]에 추가로 계약되지 않았습니까?
prabhakaran

14
u가 동일한 논리를 사용하여 여러 항목을 선택하려는 경우 :var input = "(fdw) User name (sales) safdsdf (again?)"; var output = input.Split('(', ')').Where((item, index) => index % 2 != 0).ToList();
WtFudgE

1
조심 용액 추출물 것을 sales입력 문자열에서 또한 함유 )sales(, (sales(
스테파노 Spinucci

435

가장 간단한 방법은 정규식을 사용하는 것입니다.

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

(매우 웃긴) 의견에 대한 답변으로 다음과 같은 Regex가 있습니다.

\(             # 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"

504
사람들이 "간단한 방법은 정규 표현식을 사용하는 것"이라고 말한 후이를 해독 할 수없는 상형 문자 문자열에 해당하는 양을 제공합니다 (특히 다른 사람들이 정규식을 제안하고 동일한 문제에 대해 서로 다른 상형 문자 세트를 만들 때 특히 재미 있습니다) ). :)
Deltics

47
실제로 무슨 일이 일어나고 있는지 설명 하는 답변이 스택에 충분하지 않습니다 . 훌륭한 설명 감사합니다 .
Sandy Gifford

처음에 '@'을 사용하는 경우 괄호를 벗어날 필요가 없다고 생각하십니까?
rank1

10
@ rank1 괄호를 피해야합니다. @가 여기서 제공하는 것은 백 슬래시를 벗어날 필요가 없다는 것입니다. 따라서 @가 없으면 "\\ (([^)] *) \\)"와 같습니다.
Diadistis

그러나 중첩 그룹을 잘 처리하지 못합니다. var filterRegex = new Regex(Regex.Escape("(") + "([^()]*)" + Regex.Escape(")"));
Jan Van der Haegen로

91

한 쌍의 괄호 만 있다고 가정합니다.

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

7
(판매) 대신 "판매"를 원하면 하위 문자열의 start + 1이 더 정확합니다.
Joze

1
s = "사용자) 이름 (판매)"은 어떻게됩니까?
dotnetstep

@dotnetstep 당신이 맞아야합니다 int end = s.IndexOf(")", start);. 편집을 대기열에 추가했습니다.
ChrisD

1
"(". 길이; +1보다 낫습니다. 편집을 보냈습니다. 또한 기능을 추가했습니다.
Ave

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

16

정규식이 여기에서 가장 좋은 도구 일 수 있습니다. 그들에 익숙하지 않다면 , 아주 작은 정규식 도구 인 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;
}

14
string input = "User name (sales)";

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

1
물론 첫 번째 브래킷의 위치는 한 번만 계산해야합니다.
Martin Brown

내부 괄호가있는 경우, 예 input = "User name (sales(1))를 들어 input.LastIndexOf(')')내부 괄호가 있거나없는 경우 사용할 수 있습니다 .
Ben

13

정규식? 나는 이것이 효과가 있다고 생각한다 ...

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

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

4

정규식을 사용하십시오.

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


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

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

1

다음은 정규식 사용을 피하는 범용 판독 가능 함수입니다.

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

1

정규 표현식이 매우 유용하지만 작성하기가 어렵다는 것을 알았습니다. 그래서, 나는 약간의 연구를했고 그것들을 너무 쉽게 쓰는 도구 를 찾았 습니다.

구문을 이해하기 어렵 기 때문에 부끄러워하지 마십시오. 그들은 매우 강력 할 수 있습니다.


2
SO에 오신 것을 환영합니다! 이것은 좋은 조언이지만 답변으로 게시되어서는 안됩니다. 이와 같은 일반적인 조언은 의견으로 게시해야합니다. 답은 반드시 asker의 특정 문제를 해결해야합니다. 아직 의견을 게시 할 평판이 충분하지 않다는 것을 알고 있지만 이것이 바로 담당자 임계 값이 존재하는 이유입니다. 조금 더 오래 지내면 사람들은 항상 Rubular와 같은 도구를 추천한다는 것을 알 수 있습니다 (물론 주석). 즉,이 조언은 유용 할 수 있지만 긴급하지는 않습니다.
Alan Moore

0

매우 유사한 구현에 대한 솔루션을 찾고있는 동안이 문제를 겪었습니다.

다음은 실제 코드의 스 니펫입니다. 첫 번째 문자 (인덱스 0)에서 하위 문자열을 시작합니다.

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

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

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

OP가 요청한 내용에 대한 답변은 아닙니다.
dicemaster

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;
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.