Troisième index C # d’un caractère dans une chaîne

Existe-t-il une commande permettant d’obtenir le troisième index d’un caractère dans une chaîne? Par exemple:

error: file.ext: line 10: invalid command [test:)] 

Dans la phrase ci-dessus, je veux l’index du 3ème colon, celui à côté du 10. Comment pourrais-je faire cela? Je connais ssortingng.IndexOf et ssortingng.LastIndexOf, mais dans ce cas, je souhaite obtenir l’index d’un caractère lorsqu’il est utilisé pour la troisième fois.

Ssortingng.IndexOf vous donnera l’index du premier, mais des surcharges vous donneront un sharepoint départ. Vous pouvez donc utiliser a le résultat du premier IndexOf plus un comme sharepoint départ du suivant. Et puis juste accumuler des index un nombre suffisant de fois:

 var offset = mySsortingng.IndexOf(':'); offset = mySsortingng.IndexOf(':', offset+1); var result = mySsortingng.IndexOf(':', offset+1); 

Ajoutez le traitement des erreurs à moins de savoir que mySsortingng contient au moins trois points.

Vous pourriez écrire quelque chose comme:

  public static int CustomIndexOf(this ssortingng source, char toFind, int position) { int index = -1; for (int i = 0; i < position; i++) { index = source.IndexOf(toFind, index + 1); if (index == -1) break; } return index; } 

EDIT : Évidemment, vous devez l’utiliser comme suit:

 int colonPosition = mySsortingng.CustomIndexOf(',', 3); 

Je suppose que vous voulez parsingr cette chaîne en différentes parties.

 public static void Main() { var input = @"error: file.ext: line 10: invalid command [test (: ]"; var splitted = input .Split(separator: new[] {": "}, count: 4, options: SsortingngSplitOptions.None); var severity = splitted[0]; // "error" var filename = splitted[1]; // "file.ext" var line = splitted[2]; // "line 10" var message = splitted[3]; // "invalid command [test (: ]" } 

Cela a déjà été répondu à plusieurs très bonnes manières – mais j’ai décidé d’essayer de l’écrire en utilisant Expressions.

 private int? GetNthOccurrance(ssortingng inputSsortingng, char charToFind, int occurranceToFind) { int totalOccurrances = inputSsortingng.ToCharArray().Count(c => c == charToFind); if (totalOccurrances < occurranceToFind || occurranceToFind <= 0) { return null; } var charIndex = Enumerable.Range(0, inputString.Length - 1) .Select(r => new { Position = r, Char = inputSsortingng[r], Count = 1 }) .Where(r => r.Char == charToFind); return charIndex .Select(c => new { c.Position, c.Char, Count = charIndex.Count(c2 => c2.Position <= c.Position) }) .Where(r => r.Count == occurranceToFind) .Select(r => r.Position) .First(); } 

et des tests pour le prouver aussi:

 Assert.AreEqual(0, GetNthOccurrance(input, 'h', 1)); Assert.AreEqual(3, GetNthOccurrance(input, 'l', 2)); Assert.IsNull(GetNthOccurrance(input, 'z', 1)); Assert.IsNull(GetNthOccurrance(input, 'h', 10)); 

Vous pouvez appeler .IndexOf (char, position) pour effectuer une recherche à partir de la position souhaitée. Vous devez donc l’appeler 3 fois (mais, après chaque appel, vous devez également vérifier si quelque chose a été trouvé).

 int pos = -1; for ( int k = 0; k < 3; ++k ) { pos = s.indexOf( ':', pos+1 ); // Check if pos < 0... } 

Un peu moche, mais une approche alternative (aux autres déjà postées) qui fonctionne:

 public int FindThirdColonIndex(ssortingng msg) { for (int i = 0, colonCount = 0; i < msg.Length; i++) { if (msg[i] == ':' && ++colonCount == 3) { return i; } } // Not found return -1; } 

Voici une implémentation récursive (pour ssortingng not char) – en tant que méthode d’extension, imitant le format de la ou des méthodes framework.

Tout ce que vous avez à faire est de changer “valeur de chaîne” en “valeur de caractère” dans la méthode d’extension et de mettre à jour les tests en conséquence, cela fonctionnera … Je suis heureux de le faire et de le poster si quelqu’un est intéressé?

 public static int IndexOfNth( this ssortingng input, ssortingng value, int startIndex, int nth) { if (nth < 1) throw new NotSupportedException("Param 'nth' must be greater than 0!"); if (nth == 1) input.IndexOf(value, startIndex); return input.IndexOfNth(value, input.IndexOf(value, startIndex) + 1, --nth); } 

De plus, voici quelques tests unitaires (MBUnit) qui pourraient vous aider (pour prouver que c'est correct):

 [Test] public void TestIndexOfNthWorksForNth1() { const ssortingng input = "foo
bar
baz
"; Assert.AreEqual(3, input.IndexOfNth("
", 0, 1)); } [Test] public void TestIndexOfNthWorksForNth2() { const ssortingng input = "foo
whatthedeuce
kthxbai
"; Assert.AreEqual(21, input.IndexOfNth("
", 0, 2)); } [Test] public void TestIndexOfNthWorksForNth3() { const ssortingng input = "foo
whatthedeuce
kthxbai
"; Assert.AreEqual(34, input.IndexOfNth("
", 0, 3)); }

Veuillez voir cette réponse sur une question similaire: https://stackoverflow.com/a/46460083/7673306
Il vous fournit une méthode pour trouver l’index de la nième occurrence d’un caractère spécifique dans une chaîne désignée.

Dans votre cas spécifique, il serait implémenté de la manière suivante:

 int index = IndexOfNthCharacter("error: file.ext: line 10: invalid command [test:)]", 3, ':');