Comment puis-je tronquer a.NET string?
je voudrais tronquer une chaîne de telle sorte que sa longueur ne soit pas plus longue qu'une valeur donnée. J'écris à une table de base de données et je veux m'assurer que les valeurs que j'écris respectent la contrainte du type de données de la colonne.
Par exemple, ce serait bien si je pouvais écrire ce qui suit:
string NormalizeLength(string value, int maxLength)
{
return value.Substring(0, maxLength);
}
malheureusement, cela soulève une exception parce que maxLength
dépasse généralement les limites de la chaîne de caractères value
. Bien sûr, je pourrais écrire une fonction comme les suivantes, mais j'espérais que quelque chose comme cela existe déjà.
string NormalizeLength(string value, int maxLength)
{
return value.Length <= maxLength ? value : value.Substring(0, maxLength);
}
Où est L'insaisissable API qui effectue cette tâche? Est-il un?
27 réponses
il n'y a pas de méthode Truncate()
sur string, malheureusement. Vous devez écrire ce genre de logique vous-même. Ce que vous pouvez faire, cependant, c'est envelopper ceci dans une méthode d'extension afin que vous n'ayez pas à le dupliquer partout:
public static class StringExt
{
public static string Truncate(this string value, int maxLength)
{
if (string.IsNullOrEmpty(value)) return value;
return value.Length <= maxLength ? value : value.Substring(0, maxLength);
}
}
maintenant nous pouvons écrire:
var someString = "...";
someString = someString.Truncate(2);
Ou à la place de l'opérateur ternaire, vous pouvez utiliser les Mathématiques.min
public static class StringExt
{
public static string Truncate( this string value, int maxLength )
{
if (string.IsNullOrEmpty(value)) { return value; }
return value.Substring(0, Math.Min(value.Length, maxLength));
}
}
j'ai pensé que je voudrais jeter dans mon application depuis je crois qu'il couvre tous les cas qui ont été abordés par les autres et le fait de manière concise qui est encore lisible.
public static string Truncate(this string value, int maxLength)
{
if (!string.IsNullOrEmpty(value) && value.Length > maxLength)
{
return value.Substring(0, maxLength);
}
return value;
}
cette solution s'appuie principalement sur le Ray's solution et ouvre la méthode pour une utilisation comme une méthode d'extension en utilisant le ce mot-clé tout comme LBushkin fait dans sa solution.
vous pouvez utiliser LINQ... il élimine le besoin de vérifier la longueur de la chaîne. Certes peut-être pas le plus efficace, mais c'est amusant.
string result = string.Join("", value.Take(maxLength)); // .NET 4 Join
ou
string result = new string(value.Take(maxLength).ToArray());
dans .NET 4.0 vous pouvez utiliser la méthode Take
:
string.Concat(myString.Take(maxLength));
Non testé pour l'efficacité!
le Framework .NET a une API pour tronquer une chaîne de caractères comme celle-ci:
Microsoft.VisualBasic.Strings.Left(string, int);
mais dans une application C# app, vous préférerez probablement lancer votre propre application plutôt que de prendre une dépendance sur Microsoft.VisualBasic.dll, dont la principale raison d'être est la rétrocompatibilité.
parce que les tests de performance sont amusants: (en utilisant linqpad extension methods )
var val = string.Concat(Enumerable.Range(0, 50).Select(i => i % 10));
foreach(var limit in new[] { 10, 25, 44, 64 })
new Perf<string> {
{ "newstring" + limit, n => new string(val.Take(limit).ToArray()) },
{ "concat" + limit, n => string.Concat(val.Take(limit)) },
{ "truncate" + limit, n => val.Substring(0, Math.Min(val.Length, limit)) },
{ "smart-trunc" + limit, n => val.Length <= limit ? val : val.Substring(0, limit) },
{ "stringbuilder" + limit, n => new StringBuilder(val, 0, Math.Min(val.Length, limit), limit).ToString() },
}.Vs();
la méthode truncate
était "significativement" plus rapide. # microoptimisation
Début
- truncate10 5788 tiques écoulées (0,5788 ms) [in 10K reps, 5.788 E-05 ms per]
- smart-trunc10 8206 tics écoulés (0,8206 ms) [in 10K répétitions, 8.206 E-05 ms par]
- stringbuilder10 10557 tiques écoulé (1.0557 ms) [en 10K répétitions, 0.00010557 ms par]
- concat10 45495 tiques écoulé (4.5495 ms) [en 10K répétitions, 0.00045495 ms par]
- newstring10 72535 tiques écoulé (7.2535 ms) [en 10K répétitions, 0.00072535 ms par]
en Retard
- truncate44 8835 tiques écoulé (0.8835 ms) [en 10K répétitions, 8.835 E-05 ms par]
- stringbuilder44 13106 tiques écoulé (1.3106 ms) [en 10K répétitions, 0.00013106 ms par]
- smart-trunc44 14821 tiques écoulé (1.4821 ms) [en 10K répétitions, 0.00014821 ms par]
- newstring44 144324 tiques écoulé (14.4324 ms) [en 10K répétitions, 0.00144324 ms par]
- concat44 174610 tiques écoulées (17.461 ms) [en 10K répétitions, 0.0017461 ms par]
Trop Long
- smart-trunc64 6944 tiques écoulées (0,6944 ms) [in 10K reps, 6,944 E-05 ms per]
- truncate64 7686 tiques écoulé (0.7686 ms) [en 10K répétitions, 7.686 E-05 ms par]
- stringbuilder64 13314 tiques écoulé (1.3314 ms) [en 10K répétitions, 0.00013314 ms par]
- newstring64 177481 tiques écoulé (17.7481 ms) [en 10K répétitions, 0.00177481 ms par]
- concat64 241601 tiques écoulé (24.1601 ms) [en 10K répétitions, 0.00241601 ms par]
semble que personne n'a encore posté ceci:
public static class StringExt
{
public static string Truncate(this string s, int maxLength)
{
return s != null && s.Length > maxLength ? s.Substring(0, maxLength) : s;
}
}
L'utilisation de l'opérateur & le rend légèrement meilleur que la réponse acceptée.
j'ai fait le mien dans une ligne comme celle-ci
value = value.Length > 1000 ? value.Substring(0, 1000) : value;
une variante similaire avec l'opérateur de propagation nulle de C# 6
public static string Truncate(this string value, int maxLength)
{
return value?.Length <= maxLength ? value : value?.Substring(0, maxLength);
}
veuillez noter que nous vérifions essentiellement si value
est nul deux fois ici.
en Prenant @CaffGeek et de simplification:
public static string Truncate(this string value, int maxLength)
{
return string.IsNullOrEmpty(value) ? value : value.Substring(0, Math.Min(value.Length, maxLength));
}
Kndly noter que tronquer une corde ne signifie pas simplement justing couper une corde à une longueur spécifiée seul, mais doivent prendre soin de ne pas diviser le mot.
eg string: c'est une chaîne de test.
je veux le couper à 11 . Si nous utilisons l'une des méthodes indiquées ci-dessus, le résultat sera
c'est a te
ce n'est pas ce que nous voulons
le la méthode que j'utilise peut-être aussi pas si parfait, mais il peut gérer la plupart de la situation
public string CutString(string source, int length)
{
if (source== null || source.Length < length)
{
return source;
}
int nextSpace = source.LastIndexOf(" ", length);
return string.Format("{0}...", input.Substring(0, (nextSpace > 0) ? nextSpace : length).Trim());
}
je sais que c'est une vieille question, mais voici une belle solution:
public static string Truncate(this string text, int maxLength, string suffix = "...")
{
string str = text;
if (maxLength > 0)
{
int length = maxLength - suffix.Length;
if (length <= 0)
{
return str;
}
if ((text != null) && (text.Length > maxLength))
{
return (text.Substring(0, length).TrimEnd(new char[0]) + suffix);
}
}
return str;
}
var myString = "hello world"
var myTruncatedString = myString.Truncate(4);
retourne: bonjour...
toujours pas de méthode tronquée en 2016 pour C # strings. Mais-En Utilisant La Syntaxe C# 6.0:
public static class StringExtension
{
public static string Truncate(this string s, int max)
{
return s?.Length > max ? s.Substring(0, max) : s ?? throw new ArgumentNullException(s);
}
}
il fonctionne comme un charme:
"Truncate me".Truncate(8);
Result: "Truncate"
Juste au cas où il n'y a pas assez de réponses, voici la mienne :)
public static string Truncate(this string str,
int totalLength,
string truncationIndicator = "")
{
if (string.IsNullOrEmpty(str) || str.Length < totalLength)
return str;
return str.Substring(0, totalLength - truncationIndicator.Length)
+ truncationIndicator;
}
à utiliser:
"I use it like this".Truncate(5,"~")
pourquoi pas:
string NormalizeLength(string value, int maxLength)
{
//check String.IsNullOrEmpty(value) and act on it.
return value.PadRight(maxLength).Substring(0, maxLength);
}
, c'est-à-dire dans le cas value.Length < maxLength
, des espaces au bout du coussinet ou tronquer l'excédent.
par souci de complexité, j'ajouterai ma version surchargée qui remplace les 3 derniers caractères par une ellipse par rapport au paramètre maxLength.
public static string Truncate(this string value, int maxLength, bool replaceTruncatedCharWithEllipsis = false)
{
if (replaceTruncatedCharWithEllipsis && maxLength <= 3)
throw new ArgumentOutOfRangeException("maxLength",
"maxLength should be greater than three when replacing with an ellipsis.");
if (String.IsNullOrWhiteSpace(value))
return String.Empty;
if (replaceTruncatedCharWithEllipsis &&
value.Length > maxLength)
{
return value.Substring(0, maxLength - 3) + "...";
}
return value.Substring(0, Math.Min(value.Length, maxLength));
}
je préfère la réponse de jpierson, mais aucun des exemples que je peux voir ici ne traite un paramètre invalide maxLength, comme quand maxLength < 0.
choix serait soit gérer l'erreur dans un try/catch, clamper le paramètre maxlength min à 0, ou si maxLength est inférieur à 0 retourner une chaîne vide.
code non optimisé:
public string Truncate(this string value, int maximumLength)
{
if (string.IsNullOrEmpty(value) == true) { return value; }
if (maximumLen < 0) { return String.Empty; }
if (value.Length > maximumLength) { return value.Substring(0, maximumLength); }
return value;
}
voici un vb.net solution, notez que l'instruction if (bien que laid) améliore les performances car nous n'avons pas besoin de l'instruction substring lorsque la chaîne est déjà plus petite que maxlength... En faisant une extension de chaîne, il est facile à utiliser...
<System.Runtime.CompilerServices.Extension()> _
Public Function Truncate(String__1 As String, maxlength As Integer) As String
If Not String.IsNullOrEmpty(String__1) AndAlso String__1.Length > maxlength Then
Return String__1.Substring(0, maxlength)
Else
Return String__1
End If
End Function
je sais qu'il y a déjà une tonne de réponses mais mon besoin était de garder le début et la fin de la corde intact mais raccourcir à la longueur max.
public static string TruncateMiddle(string source)
{
if (String.IsNullOrWhiteSpace(source) || source.Length < 260)
return source;
return string.Format("{0}...{1}",
source.Substring(0, 235),
source.Substring(source.Length - 20));
}
ceci est pour créer des URLs SharePoint qui ont une longueur maximale de 260 caractères.
Je n'ai pas fait de longueur un paramètre puisqu'il s'agit d'une constante 260. Je n'ai pas non plus fait de la première longueur de la sous-couche un paramètre parce que je veux qu'elle se casse à un point précis. Enfin, l' la deuxième sous-couche est la longueur du source-20 puisque je connais la structure du dossier.
cela pourrait facilement être adapté à vos besoins spécifiques.
TruncateString
public static string _TruncateString(string input, int charaterlimit)
{
int characterLimit = charaterlimit;
string output = input;
// Check if the string is longer than the allowed amount
// otherwise do nothing
if (output.Length > characterLimit && characterLimit > 0)
{
// cut the string down to the maximum number of characters
output = output.Substring(0, characterLimit);
// Check if the character right after the truncate point was a space
// if not, we are in the middle of a word and need to remove the rest of it
if (input.Substring(output.Length, 1) != " ")
{
int LastSpace = output.LastIndexOf(" ");
// if we found a space then, cut back to that space
if (LastSpace != -1)
{
output = output.Substring(0, LastSpace);
}
}
// Finally, add the "..."
output += "...";
}
return output;
}
je recommande d'utiliser la méthode du substrat pour la même fonctionnalité efficace.
// Gets first n characters.
string subString = inputString.Substring(0, n);
cela a l'avantage de vous permettre d'épiler votre chaîne de chaque côté ou même quelque part au milieu sans écrire des méthodes supplémentaires. Espérons que cela aide :)
pour référence supplémentaire: https://www.dotnetperls.com/substring
je sais qu'il y a déjà une tonne de réponses ici, mais c'est celle que j'ai choisie, qui gère à la fois les chaînes nulles et la situation où la longueur passée est négative:
public static string Truncate(this string s, int length)
{
return string.IsNullOrEmpty(s) || s.Length <= length ? s
: length <= 0 ? string.Empty
: s.Substring(0, length);
}
il n'y a rien dans .net pour cela que je sache - voici ma version qui ajoute"...":
public static string truncateString(string originalString, int length) {
if (string.IsNullOrEmpty(originalString)) {
return originalString;
}
if (originalString.Length > length) {
return originalString.Substring(0, length) + "...";
}
else {
return originalString;
}
}
public static string Truncate( this string value, int maxLength )
{
if (string.IsNullOrEmpty(value)) { return value; }
return new string(value.Take(maxLength).ToArray());// use LINQ and be happy
}
Chaîne Tronquée
public static string TruncateText(string strText, int intLength)
{
if (!(string.IsNullOrEmpty(strText)))
{
// split the text.
var words = strText.Split(' ');
// calculate the number of words
// based on the provided characters length
// use an average of 7.6 chars per word.
int wordLength = Convert.ToInt32(Math.Ceiling(intLength / 7.6));
// if the text is shorter than the length,
// display the text without changing it.
if (words.Length <= wordLength)
return strText.Trim();
// put together a shorter text
// based on the number of words
return string.Join(" ", words.Take(wordLength)) + " ...".Trim();
}
else
{
return "";
}
}
C'est le code que j'utilise habituellement:
string getSubString(string value, int index, int length)
{
if (string.IsNullOrEmpty(value) || value.Length <= length)
{
return value;
}
System.Text.StringBuilder sb = new System.Text.StringBuilder();
for (int i = index; i < length; i++)
{
sb.AppendLine(value[i].ToString());
}
return sb.ToString();
}