




Может быть, регулярное выражение? Думаю, это сработает ...
\(([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"
Мне нравится, когда люди говорят «простой способ - использовать регулярные выражения», а затем предлагают то, что составляет строку нерасшифровываемых иероглифов (особенно весело, когда разные люди предлагают регулярное выражение, и каждый придумывает свой набор иероглифов для одной и той же задачи. ). :)
В стеке почти не хватает ответов, которые на самом деле объяснять, что происходит. Спасибо за прекрасное объяснение.
Если вы используете '@' в начале, я думаю, вам не нужно избегать скобок?
@ rank1 вы должны избегать скобок. @ Предлагает здесь то, что вам не нужно избегать обратной косой черты. Таким образом, без @ это будет похоже на «\\ (([^)] *) \\)».
Однако это плохо обрабатывает вложенные группы. Поменял на var filterRegex = new Regex(Regex.Escape("(") + "([^()]*)" + Regex.Escape(")"));
Спасибо за (очень забавные) комментарии, которые позволили нам получить такое прекрасное объяснение ... Мне не понравилось регулярное выражение, после этого объяснения я буду использовать. спасибо вам обоим за полезный аргумент. @Deltics
как насчет вложенных скобок
Заставляет меня уважать математика Стивена Коула Клини как парня, который придумал концепцию регулярного выражения в 1950-х годах.
string input = "User name (sales)";
string output = input.Substring(input.IndexOf('(') + 1, input.IndexOf(')') - input.IndexOf('(') - 1);
Разумеется, вам следует рассчитать положение первой скобки только один раз.
В случае, если у вас есть внутренняя скобка, например. input = "User name (sales(1)), возможно, вы захотите использовать input.LastIndexOf(')'), который будет работать, если есть внутренние скобки или нет.
Предполагая, что у вас есть только одна пара скобок.
string s = "User name (sales)";
int start = s.IndexOf("(") + 1;
int end = s.IndexOf(")", start);
string result = s.Substring(start, end - start);
начало + 1 в подстроке правильнее, если вы хотите "продажи" вместо (продажи)
что произойдет с s = "Имя пользователя) (Продажи)"?
@dotnetstep ты прав должен быть int end = s.IndexOf(")", start);. Я поставил в очередь редактирование ...
"(" .Length; лучше, чем +1. Отправлено изменение. Также добавлена функция.
Используйте регулярное выражение:
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];
Честно говоря, это должно было быть выбрано в качестве ответа.
Разве это не будет дальше сжато во input.Split ("()". ToCharArray ()) [1]
и в случае, если вы хотите использовать ту же логику для выбора нескольких: var input = "(fdw) User name (sales) safdsdf (again?)"; var output = input.Split('(', ')').Where((item, index) => index % 2 != 0).ToList();
имейте в виду, что это решение извлекает sales также из входных строк, содержащих )sales(, (sales( и т. д.
простой ответ, лучший ответ +1
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.
Я считаю, что регулярные выражения чрезвычайно полезны, но их очень сложно писать. Итак, я провел небольшое исследование и нашел этот инструмент, который упрощает их написание.
Не уклоняйтесь от них, потому что синтаксис сложно понять. Они могут быть такими могущественными.
Добро пожаловать в SO! Это хороший совет, но его не следовало публиковать в качестве ответа. Подобные общие советы следует публиковать в виде комментариев, если они вообще есть. Ответ должен касаться конкретной проблемы спрашивающего. Я знаю, что у вас пока недостаточно очков репутации, чтобы оставлять комментарии, но именно поэтому существует порог репутации. Побывав немного дольше, вы увидите, что люди всегда рекомендуют такие инструменты, как Rubular (конечно, в комментариях). Другими словами, этот совет может быть полезным, но не срочным.
Этот код быстрее, чем большинство решений здесь (если не все), упакован как Нитьметод расширения, он не поддерживает рекурсивное вложение:
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);
Покажи нам, что ты пробовал. Вы смотрели на использование регулярных выражений?