J'ai une chaîne User name (sales)
et je souhaite extraire le texte entre crochets. Comment procéderais-je?
Je soupçonne une sous-chaîne mais je ne sais pas comment lire avant le crochet de fermeture, la longueur du texte pouvant varier.
Un moyen très simple de le faire est d'utiliser des expressions régulières:
Regex.Match("User name (sales)", @"\(([^)]*)\)").Groups[1].Value
En réponse au commentaire (très amusant), voici le même Regex avec quelques explications:
\( # 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"
Si vous souhaitez vous éloigner des expressions régulières, voici la façon la plus simple de procéder:
string input = "User name (sales)";
string output = input.Split('(', ')')[1];
En supposant que vous n’ayez qu’une paire de parenthèses.
string s = "User name (sales)";
int start = s.IndexOf("(") + 1;
int end = s.IndexOf(")", start);
string result = s.Substring(start, end - start);
Utilisez cette fonction:
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));
}
et voici l'usage:
GetSubstringByString("(", ")", "User name (sales)")
et le résultat serait:
sales
Les expressions régulières pourraient être le meilleur outil ici. Si vous ne les connaissez pas, je vous recommande d’installer Expresso - un excellent petit outil regex.
Quelque chose comme:
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.Substring(input.IndexOf('(') + 1, input.IndexOf(')') - input.IndexOf('(') - 1);
Une regex peut-être? Je pense que cela fonctionnerait ...
\(([a-z]+?)\)
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;
}
Utilisez une expression régulière:
string test = "(test)";
string Word = Regex.Match(test, @"\((\w+)\)").Groups[1].Value;
Console.WriteLine(Word);
input.Remove(input.IndexOf(')')).Substring(input.IndexOf('(') + 1);
La méthode regex
est supérieure, je pense, mais si vous vouliez utiliser l'humble 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);
ou
string input = "my name is (Jayne C)";
string output = input.Substring(input.IndexOf("(") +1, input.IndexOf(")")- input.IndexOf("(")- 1);
int start = input.IndexOf("(") + 1;
int length = input.IndexOf(")") - start;
output = input.Substring(start, length);
Je trouve que les expressions régulières sont extrêmement utiles mais très difficiles à écrire. J'ai donc fait quelques recherches et trouvé cet outil qui les rend si faciles à écrire.
Ne les craignez pas, car la syntaxe est difficile à comprendre. Ils peuvent être si puissants.
Ce code est plus rapide que la plupart des solutions ici (si pas toutes), compressé sous la forme Stringméthode d'extension , il ne prend pas en charge l'imbrication récursive:
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;
}
Celui-ci est un peu plus long et lent, mais il gère plus facilement l'imbrication récursive:
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;
}
Voici une fonction lisible à des fins générales qui évite d’utiliser regex:
// 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);
}
Pour l'appeler dans votre exemple particulier, vous pouvez faire:
string result = ExtractBetween("User name (sales)", "(", ")");
Je suis tombé sur cela alors que je cherchais une solution à une implémentation très similaire.
Voici un extrait de mon code actuel. Démarre la sous-chaîne à partir du premier caractère (index 0).
string separator = "\n"; //line terminator
string output;
string input= "HowAreYou?\nLets go there!";
output = input.Substring(0, input.IndexOf(separator));