我有一个字符串用户名(销售),我想提取括号之间的文本,我该如何做到这一点?
我怀疑子字符串,但我不知道如何阅读,直到右括号,文本的长度会有所不同。
我有一个字符串用户名(销售),我想提取括号之间的文本,我该如何做到这一点?
我怀疑子字符串,但我不知道如何阅读,直到右括号,文本的长度会有所不同。
当前回答
我认为regex方法更好,但如果你想使用卑微的子字符串
string input= "my name is (Jayne C)";
int start = input.IndexOf("(");
int stop = input.IndexOf(")");
string output = input.Substring(start+1, stop - start - 1);
or
string input = "my name is (Jayne C)";
string output = input.Substring(input.IndexOf("(") +1, input.IndexOf(")")- input.IndexOf("(")- 1);
其他回答
这段代码比这里的大多数解决方案(如果不是全部的话)都快,打包为String扩展方法,它不支持递归嵌套:
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;
}
也许是正则表达式?我认为这行得通……
\(([a-z]+?)\)
正则表达式可能是这里最好的工具。如果你不熟悉它们,我建议你安装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;
}
如果你想远离正则表达式,我能想到的最简单的方法是:
string input = "User name (sales)";
string output = input.Split('(', ')')[1];
我最近一直在使用和滥用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 "";
}