Как извлечь текст, заключенный в круглые скобки?

У меня есть строка User name (sales), и я хочу извлечь текст между скобками, как мне это сделать?

Я подозреваю, что подстрока, но я не могу понять, как читать до закрывающей скобки, длина текста будет отличаться.

Покажи нам, что ты пробовал. Вы смотрели на использование регулярных выражений?

George Stocker 18.12.2008 19:37
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
237
1
356 202
17

Ответы 17

Может быть, регулярное выражение? Думаю, это сработает ...

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

Регулярные выражения могут быть здесь лучшим инструментом. Если вы не знакомы с ними, я рекомендую вам установить Экспрессо - отличный небольшой инструмент для регулярных выражений.

Что-то вроде:

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

Очень простой способ сделать это - использовать регулярные выражения:

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"

Мне нравится, когда люди говорят «простой способ - использовать регулярные выражения», а затем предлагают то, что составляет строку нерасшифровываемых иероглифов (особенно весело, когда разные люди предлагают регулярное выражение, и каждый придумывает свой набор иероглифов для одной и той же задачи. ). :)

Deltics 26.03.2010 06:14

В стеке почти не хватает ответов, которые на самом деле объяснять, что происходит. Спасибо за прекрасное объяснение.

Sandy Gifford 15.10.2013 01:02

Если вы используете '@' в начале, я думаю, вам не нужно избегать скобок?

rank1 27.11.2013 21:12

@ rank1 вы должны избегать скобок. @ Предлагает здесь то, что вам не нужно избегать обратной косой черты. Таким образом, без @ это будет похоже на «\\ (([^)] *) \\)».

Diadistis 28.11.2013 15:10

Однако это плохо обрабатывает вложенные группы. Поменял на var filterRegex = new Regex(Regex.Escape("(") + "([^()]*)" + Regex.Escape(")"));

Jan Van der Haegen 14.01.2016 21:27

Спасибо за (очень забавные) комментарии, которые позволили нам получить такое прекрасное объяснение ... Мне не понравилось регулярное выражение, после этого объяснения я буду использовать. спасибо вам обоим за полезный аргумент. @Deltics

MBH 22.06.2016 10:42

как насчет вложенных скобок

v.oddou 06.07.2016 10:21

Заставляет меня уважать математика Стивена Коула Клини как парня, который придумал концепцию регулярного выражения в 1950-х годах.

Harvey Darvey 24.02.2017 22:50
string input = "User name (sales)";

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

Разумеется, вам следует рассчитать положение первой скобки только один раз.

Martin Brown 18.12.2008 22:29

В случае, если у вас есть внутренняя скобка, например. input = "User name (sales(1)), возможно, вы захотите использовать input.LastIndexOf(')'), который будет работать, если есть внутренние скобки или нет.

Ben 05.01.2015 13:30

Предполагая, что у вас есть только одна пара скобок.

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

начало + 1 в подстроке правильнее, если вы хотите "продажи" вместо (продажи)

Joze 19.10.2011 15:24

что произойдет с s = "Имя пользователя) (Продажи)"?

dotnetstep 15.11.2013 13:54

@dotnetstep ты прав должен быть int end = s.IndexOf(")", start);. Я поставил в очередь редактирование ...

ChrisD 22.02.2014 00:36

"(" .Length; лучше, чем +1. Отправлено изменение. Также добавлена ​​функция.

Ave 01.12.2014 01:39

Используйте регулярное выражение:

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

Я думаю, что метод 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);

Используйте эту функцию:

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

Если вы не хотите использовать регулярные выражения, я могу придумать самый простой способ:

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

Честно говоря, это должно было быть выбрано в качестве ответа.

Pat Lindley 11.01.2013 22:58

Разве это не будет дальше сжато во input.Split ("()". ToCharArray ()) [1]

prabhakaran 12.05.2014 13:55

и в случае, если вы хотите использовать ту же логику для выбора нескольких: var input = "(fdw) User name (sales) safdsdf (again?)"; var output = input.Split('(', ')').Where((item, index) => index % 2 != 0).ToList();

WtFudgE 25.04.2016 13:36

имейте в виду, что это решение извлекает sales также из входных строк, содержащих )sales(, (sales( и т. д.

Stefano Spinucci 15.08.2019 11:36

простой ответ, лучший ответ +1

Al-Hanash Moataz 15.12.2020 03:55
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;
}

Вот читаемая функция общего назначения, которая избегает использования регулярных выражений:

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

Я столкнулся с этим, когда искал решение для очень похожей реализации.

Вот отрывок из моего реального кода. Начинает подстроку с первого символа (индекс 0).

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

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

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

Это не отвечает на вопрос OP.

dicemaster 12.07.2018 14:34

Я считаю, что регулярные выражения чрезвычайно полезны, но их очень сложно писать. Итак, я провел небольшое исследование и нашел этот инструмент, который упрощает их написание.

Не уклоняйтесь от них, потому что синтаксис сложно понять. Они могут быть такими могущественными.

Добро пожаловать в SO! Это хороший совет, но его не следовало публиковать в качестве ответа. Подобные общие советы следует публиковать в виде комментариев, если они вообще есть. Ответ должен касаться конкретной проблемы спрашивающего. Я знаю, что у вас пока недостаточно очков репутации, чтобы оставлять комментарии, но именно поэтому существует порог репутации. Побывав немного дольше, вы увидите, что люди всегда рекомендуют такие инструменты, как Rubular (конечно, в комментариях). Другими словами, этот совет может быть полезным, но не срочным.

Alan Moore 18.02.2015 18:11

Этот код быстрее, чем большинство решений здесь (если не все), упакован как Нитьметод расширения, он не поддерживает рекурсивное вложение:

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;
}
int start = input.IndexOf("(") + 1;
int length = input.IndexOf(")") - start;
output = input.Substring(start, length);

Очень похоже на @Gustavo Baiocchi Costa, но смещение рассчитывается с другим промежуточным Substring.

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

Другие вопросы по теме