6
votes

Supprimer tous les caractères après la dernière lettre

Le programme simple suivant trouvera la dernière lettre d'une chaîne qu'un utilisateur entre puis tout en retirant tout ce point. Donc, si une personne entre une chaîne .... tout après que le g doit être supprimé. J'ai ce qui suit comme un petit programme: XXX

J'ai essayé de nombreuses variantes de cela et aucun d'entre eux ne l'obtienne exactement. Ce programme particulier avec une entrée de chaîne .... La sortie du programme est strin. Il en va de même en quelque sorte sur ce qu'il devrait emporter et qu'il prend réellement les lettres à l'extérieur que cela ne devrait pas. Quelqu'un peut-il donner une indication sur la raison pour laquelle cela se produit? La sortie souhaitée, à nouveau doit être String .


3 commentaires

Pourquoi pas simplement utiliser entrée.Substring (0, x + 1) ?


@Grant Thomas: Parce que x pourrait être -1 s'il n'existe pas et que tout est enlevé, c'est peut-être l'intention, ce n'est pas vraiment clair de la "spécification".


@Michelkeijzers qui n'est pas pertinent. Le point est que toute la boucle est une farce - la validation de la valeur est triviale.


10 Réponses :


5
votes

Essayez ceci:

string input = Console.ReadLine();                // ABC.ABC.
int index = input.Select((c, i) => new { c, i })
                 .Where(x => char.IsLetter(x.c))
                 .Max(x => x.i);
string trimmedInput = input.Substring(0, index + 1);
Console.WriteLine(trimmedInput);                  // ABC.ABC


4 commentaires

+1 Pas besoin de sous-chaîne . string.join ("", entrée.takewhile (char.sletter))


Cela échouera! Cela ne recherchera pas la dernière lettre, il cherchera la première non-lettre et supprimera le reste, y compris les lettres qui arrivent après.


Oui, cela échoue sur "abc.abc." qui (selon la spécification) devrait produire "abc.abc"


@MartinMulder / Matthewwatson n'est pas aussi élégant que ma solution initiale, mais elle satisfait mieux aux exigences.



2
votes

Je pense que ce serait beaucoup plus droit de tout simplement SUBSTRING La chaîne L'utilisateur entré. Alors, considérez le code modifié suivant: xxx

ici, nous stockons la valeur que l'utilisateur entré dans s , trouve le dernier index d'une lettre, puis Substring à travers cette lettre lorsque vous écrivez à la console.


2 commentaires

Une solution plus élégante au problème que le mien, je serais à dire. +1


Cela permettra de rechercher deux fois la gamme de caractères.



1
votes

Vous pouvez également utiliser une fonction de chaîne appelée sous-chaîne, pour tout obtenir de la première à l'index de la dernière lettre.


2 commentaires

Avez-vous une idée de ce que le programme se comporte de la façon dont il est maintenant?


Lorsque vous enlevez, vous faites: pour (int i = x; i



3
votes

Jsut pour l'explication, c'est parce que chaque fois que vous supprimez un personnage, vous incrémentez le comptoir I mais en décrémentant un charlist.Compte, vous éliminez donc un caractère de 1 caractère, laissant la suivante, puis retirez-la à nouveau et ainsi de suite .. .

Par exemple, avec l'entrée "chaîne ...." et x étant 5 (index de la lettre G) que vous faites:

1ère itération: Supprimer le G Char SO x devient 6 et Charlist.count devient 9 (10-1)

prochaine itération: Supprimez le char à Index 6 qui est maintenant le second. (votre chaîne étant "sincère" . .. ").

Vous avez donc manqué le premier point.

Je vous ai laissé vérifier d'autres réponses car ils contiennent des solutions plus élégantes à vos problèmes.


1 commentaires

C'est ce que je cherchais. Merci pour cette perspicacité, je suis sûr que cela m'aidera sur la ligne quelque part.



0
votes

Ceci correspondra à tous les caractères de mot (A-Z, 0-9 et _):

string Input = Console.ReadLine();
string Userinput = String.Empty;
Regex TextSearch = new Regex(@"\w*");

if(TextSearch.IsMatch(Input))
    Userinput = TextSearch.Match(Input).Groups[0].Value;
else
    // No valid Input



0
votes

Ce que je crois serait l'option la plus courte et la plus simple:

edit: un commentaire a indiqué une erreur initiale ici, alors j'ai ajouté un petit correctif. Devrait fonctionner bien maintenant (pourrait ne pas être la solution optimale, mais je pensais que c'était une solution simple de toute façon): xxx


4 commentaires

Cela échouera! Cela ne recherchera pas la dernière lettre, il cherchera la première non-lettre et supprimera le reste, y compris les lettres qui arrivent après.


@MartinMulder Merci d'avoir souligné cela, vous avez tout à fait raison. Fait un peu de changement maintenant, alors je crois que cela devrait être correct maintenant.


Super ... Mais ... Sachez que cette réponse a déjà été présentée par Matthew Watson.


Coïncidence, alors quoi? Ma réponse originale était ici d'abord et corrigée avec une touche mineure. Grosse affaire. (En plus, le mien est sans doute plus lisible, à la fois initialement et après la modification;))



2
votes
string s = console.ReadLine();
s = s.Substring(0, s.ToList().FindLastIndex(char.IsLetter) + 1);

0 commentaires

1
votes

Voici une façon assez inefficace de le faire (juste pour le plaisir!)

var trimmedInput = string.Join("", input.Reverse().SkipWhile(x => !char.IsLetter(x)).Reverse());


2 commentaires

Si c'est tellement inefficace, pourquoi le poster?


@MartinMulder "juste pour le plaisir". Peut-être que ce n'est pas votre genre de chose! Mais cela démontre certaines utilisations de Linq pour inverser des séquences, ce qui peut être d'un certain intérêt.



1
votes

Vous pouvez utiliser cette extension: xxx

entrée: test ... ABC ... Sortie: Test ... ABC

Démo


0 commentaires

1
votes

solution sera comme ça.

string charList = "string..."; //any string place here
int x = charList.LastIndexOf(charList.Last(char.IsLetter));
String str = charList.ToString().Substring(0, x + 1);


0 commentaires