Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Notitie
In dit artikel vindt u aanvullende opmerkingen in de referentiedocumentatie voor deze API.
Een tekenreeks is een opeenvolgende verzameling tekens die worden gebruikt om tekst weer te geven. Een object is een opeenvolgende verzameling String objecten die een tekenreeks vertegenwoordigen. Een System.CharSystem.Char object komt overeen met een UTF-16-code-eenheid. De waarde van het String-object is de inhoud van de sequentiële verzameling System.Char-objecten, en die waarde is onveranderbaar (dat betekent, het is alleen-lezen). Zie de sectie Onveranderlijkheid en de StringBuilder-klasse voor meer informatie over de onveranderbaarheid van tekenreeksen. De maximale grootte van een String object in het geheugen is 2 GB of ongeveer 1 miljard tekens.
Zie Inleiding tot tekencodering in .NET voor meer informatie over Unicode, UTF-16, code-eenheden, codepunten en de Char typen Rune.
Een tekenreeksobject instantiëren
U kunt een String object op de volgende manieren instantiëren:
Door een letterlijke tekenreeks toe te wijzen aan een String variabele. Dit is de meest gebruikte methode voor het maken van een tekenreeks. In het volgende voorbeeld wordt de toewijzing gebruikt om verschillende tekenreeksen te maken. Houd er rekening mee dat in C# en F# de backslash (\) een escapeteken is, waardoor letterlijke backslashes in een tekenreeks moeten worden geëscaped, of dat de gehele tekenreeks moet worden voorafgegaan door een '@'-teken.
string string1 = "This is a string created by assignment."; Console.WriteLine(string1); string string2a = "The path is C:\\PublicDocuments\\Report1.doc"; Console.WriteLine(string2a); string string2b = @"The path is C:\PublicDocuments\Report1.doc"; Console.WriteLine(string2b); // The example displays the following output: // This is a string created by assignment. // The path is C:\PublicDocuments\Report1.doc // The path is C:\PublicDocuments\Report1.doclet string1 = "This is a string created by assignment." printfn "%s" string1 let string2a = "The path is C:\\PublicDocuments\\Report1.doc" printfn "%s" string2a let string2b = @"The path is C:\PublicDocuments\Report1.doc" printfn "%s" string2b // The example displays the following output: // This is a string created by assignment. // The path is C:\PublicDocuments\Report1.doc // The path is C:\PublicDocuments\Report1.docDim string1 As String = "This is a string created by assignment." Console.WriteLine(string1) Dim string2 As String = "The path is C:\PublicDocuments\Report1.doc" Console.WriteLine(string2) ' The example displays the following output: ' This is a string created by assignment. ' The path is C:\PublicDocuments\Report1.docDoor een String klasseconstructor aan te roepen. In het volgende voorbeeld worden tekenreeksen geïnstantieerd door verschillende class constructors aan te roepen. Sommige constructors bevatten aanwijzers naar tekenmatrices of ondertekende bytematrices als parameters. Visual Basic biedt geen ondersteuning voor aanroepen naar deze constructors. Zie voor gedetailleerde informatie over String constructors de samenvatting van de String constructor.
char[] chars = { 'w', 'o', 'r', 'd' }; sbyte[] bytes = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x00 }; // Create a string from a character array. string string1 = new string(chars); Console.WriteLine(string1); // Create a string that consists of a character repeated 20 times. string string2 = new string('c', 20); Console.WriteLine(string2); string stringFromBytes = null; string stringFromChars = null; unsafe { fixed (sbyte* pbytes = bytes) { // Create a string from a pointer to a signed byte array. stringFromBytes = new string(pbytes); } fixed (char* pchars = chars) { // Create a string from a pointer to a character array. stringFromChars = new string(pchars); } } Console.WriteLine(stringFromBytes); Console.WriteLine(stringFromChars); // The example displays the following output: // word // cccccccccccccccccccc // ABCDE // wordlet chars = [| 'w'; 'o'; 'r'; 'd' |] let bytes = [| 0x41y; 0x42y; 0x43y; 0x44y; 0x45y; 0x00y |] // Create a string from a character array. let string1 = String chars printfn "%s" string1 // Create a string that consists of a character repeated 20 times. let string2 = String('c', 20) printfn "%s" string2 let stringFromBytes = // Create a string from a pointer to a signed byte array. use pbytes = fixed bytes String pbytes let stringFromChars = // Create a string from a pointer to a character array. use pchars = fixed chars String pchars printfn $"{stringFromBytes}" printfn $"{stringFromChars}" // The example displays the following output: // word // cccccccccccccccccccc // ABCDE // wordDim chars() As Char = {"w"c, "o"c, "r"c, "d"c} ' Create a string from a character array. Dim string1 As New String(chars) Console.WriteLine(string1) ' Create a string that consists of a character repeated 20 times. Dim string2 As New String("c"c, 20) Console.WriteLine(string2) ' The example displays the following output: ' word ' ccccccccccccccccccccDoor de operator voor tekenreekssamenvoeging (+ in C# en F# en & of + in Visual Basic) te gebruiken om één tekenreeks te maken op basis van een combinatie van String exemplaren en letterlijke tekenreeksen. In het volgende voorbeeld ziet u het gebruik van de operator tekenreekssamenvoeging.
string string1 = "Today is " + DateTime.Now.ToString("D") + "."; Console.WriteLine(string1); string string2 = "This is one sentence. " + "This is a second. "; string2 += "This is a third sentence."; Console.WriteLine(string2); // The example displays output like the following: // Today is Tuesday, July 06, 2011. // This is one sentence. This is a second. This is a third sentence.let string1 = "Today is " + DateTime.Now.ToString("D") + "." printfn $"{string1}" let string2 = "This is one sentence. " + "This is a second. " let string2 = string2 + "This is a third sentence." printfn $"{string2}" // The example displays output like the following: // Today is Tuesday, July 06, 2011. // This is one sentence. This is a second. This is a third sentence.Dim string1 As String = "Today is " + Date.Now.ToString("D") + "." Console.WriteLine(string1) Dim string2 As String = "This is one sentence. " + "This is a second. " string2 += "This is a third sentence." Console.WriteLine(string2) ' The example displays output like the following: ' Today is Tuesday, July 06, 2011. ' This is one sentence. This is a second. This is a third sentence.Door een eigenschap op te halen of een methode aan te roepen die een tekenreeks retourneert. In het volgende voorbeeld worden de methoden van de String klasse gebruikt om een subtekenreeks uit een grotere tekenreeks te extraheren.
string sentence = "This sentence has five words."; // Extract the second word. int startPosition = sentence.IndexOf(" ") + 1; string word2 = sentence.Substring(startPosition, sentence.IndexOf(" ", startPosition) - startPosition); Console.WriteLine("Second word: " + word2); // The example displays the following output: // Second word: sentencelet sentence = "This sentence has five words." // Extract the second word. let startPosition = sentence.IndexOf " " + 1 let word2 = sentence.Substring(startPosition, sentence.IndexOf(" ", startPosition) - startPosition) printfn $"Second word: {word2}" // The example displays the following output: // Second word: sentenceDim sentence As String = "This sentence has five words." ' Extract the second word. Dim startPosition As Integer = sentence.IndexOf(" ") + 1 Dim word2 As String = sentence.Substring(startPosition, sentence.IndexOf(" ", startPosition) - startPosition) Console.WriteLine("Second word: " + word2) ' The example displays the following output: ' Second word: sentenceDoor een opmaakmethode aan te roepen om een waarde of object te converteren naar de tekenreeksweergave. In het volgende voorbeeld wordt de samengestelde opmaakfunctie gebruikt om de tekenreeksweergave van twee objecten in een tekenreeks op te nemen.
DateTime dateAndTime = new DateTime(2011, 7, 6, 7, 32, 0); double temperature = 68.3; string result = String.Format("At {0:t} on {0:D}, the temperature was {1:F1} degrees Fahrenheit.", dateAndTime, temperature); Console.WriteLine(result); // The example displays the following output: // At 7:32 AM on Wednesday, July 06, 2011, the temperature was 68.3 degrees Fahrenheit.let dateAndTime = DateTime(2011, 7, 6, 7, 32, 0) let temperature = 68.3 String.Format("At {0:t} on {0:D}, the temperature was {1:F1} degrees Fahrenheit.", dateAndTime, temperature) |> printfn "%s" // The example displays the following output: // At 7:32 AM on Wednesday, July 06, 2011, the temperature was 68.3 degrees Fahrenheit.Dim dateAndTime As DateTime = #07/06/2011 7:32:00AM# Dim temperature As Double = 68.3 Dim result As String = String.Format("At {0:t} on {0:D}, the temperature was {1:F1} degrees Fahrenheit.", dateAndTime, temperature) Console.WriteLine(result) ' The example displays the following output: ' At 7:32 AM on Wednesday, July 06, 2011, the temperature was 68.3 degrees Fahrenheit.
Tekenobjecten en Unicode-tekens
Elk teken in een tekenreeks wordt gedefinieerd door een Unicode-scalaire waarde, ook wel een Unicode-codepunt of de rangtelwaarde (numeriek) van het Unicode-teken genoemd. Elk codepunt wordt gecodeerd met UTF-16-codering en de numerieke waarde van elk element van de codering wordt vertegenwoordigd door een Char object.
Notitie
Omdat een String exemplaar bestaat uit een sequentiële verzameling UTF-16-code-eenheden, is het mogelijk om een String object te maken dat geen goed opgemaakte Unicode-tekenreeks is. Het is bijvoorbeeld mogelijk om een tekenreeks te maken met een lage surrogaat zonder een bijbehorende hoge surrogaat. Hoewel sommige methoden, zoals de methoden voor het coderen en decoderen van objecten in de System.Text naamruimte, controles kunnen uitvoeren om ervoor te zorgen dat tekenreeksen goed zijn gevormd, String zorgen klasseleden er niet voor dat een tekenreeks goed is gevormd.
Een enkel Char object vertegenwoordigt meestal één codepunt, dat wil gezegd de numerieke waarde van het Char gelijk aan het codepunt. Het codepunt voor het teken 'a' is bijvoorbeeld U+0061. Voor een codepunt is echter mogelijk meer dan één gecodeerd element vereist (meer dan één Char object). De Unicode-standaard definieert twee typen tekens die overeenkomen met meerdere Char objecten: grafemes en Unicode-aanvullende codepunten die overeenkomen met tekens in de aanvullende Unicode-vlakken.
Een graaf wordt vertegenwoordigd door een basisteken, gevolgd door een of meer combinatietekens. Het teken ä wordt bijvoorbeeld vertegenwoordigd door een Char object waarvan het codepunt U+0061 is, gevolgd door een Char object waarvan het codepunt U+0308 is. Dit teken kan ook worden gedefinieerd door één Char object met een codepunt van U+00E4. Zoals in het volgende voorbeeld wordt weergegeven, geeft een cultuurgevoelige vergelijking voor gelijkheid aan dat deze twee representaties gelijk zijn, hoewel een gewone rangtelvergelijking dat niet doet. Als de twee tekenreeksen echter zijn genormaliseerd, geeft een ordinale vergelijking ook aan dat ze gelijk zijn. (Zie voor meer informatie over het normaliseren van tekenreeksen de Normalisatiesectie.)
using System; using System.Globalization; using System.IO; public class Example5 { public static void Main() { StreamWriter sw = new StreamWriter(@".\graphemes.txt"); string grapheme = "\u0061\u0308"; sw.WriteLine(grapheme); string singleChar = "\u00e4"; sw.WriteLine(singleChar); sw.WriteLine("{0} = {1} (Culture-sensitive): {2}", grapheme, singleChar, String.Equals(grapheme, singleChar, StringComparison.CurrentCulture)); sw.WriteLine("{0} = {1} (Ordinal): {2}", grapheme, singleChar, String.Equals(grapheme, singleChar, StringComparison.Ordinal)); sw.WriteLine("{0} = {1} (Normalized Ordinal): {2}", grapheme, singleChar, String.Equals(grapheme.Normalize(), singleChar.Normalize(), StringComparison.Ordinal)); sw.Close(); } } // The example produces the following output: // ä // ä // ä = ä (Culture-sensitive): True // ä = ä (Ordinal): False // ä = ä (Normalized Ordinal): Trueopen System open System.IO do use sw = new StreamWriter(@".\graphemes.txt") let grapheme = "\u0061\u0308" sw.WriteLine grapheme let singleChar = "\u00e4" sw.WriteLine singleChar sw.WriteLine("{0} = {1} (Culture-sensitive): {2}", grapheme, singleChar, String.Equals(grapheme, singleChar, StringComparison.CurrentCulture)) sw.WriteLine("{0} = {1} (Ordinal): {2}", grapheme, singleChar, String.Equals(grapheme, singleChar, StringComparison.Ordinal)) sw.WriteLine("{0} = {1} (Normalized Ordinal): {2}", grapheme, singleChar, String.Equals(grapheme.Normalize(), singleChar.Normalize(), StringComparison.Ordinal)) // The example produces the following output: // ä // ä // ä = ä (Culture-sensitive): True // ä = ä (Ordinal): False // ä = ä (Normalized Ordinal): TrueImports System.Globalization Imports System.IO Module Example9 Public Sub Main() Dim sw As New StreamWriter(".\graphemes.txt") Dim grapheme As String = ChrW(&H61) + ChrW(&H308) sw.WriteLine(grapheme) Dim singleChar As String = ChrW(&HE4) sw.WriteLine(singleChar) sw.WriteLine("{0} = {1} (Culture-sensitive): {2}", grapheme, singleChar, String.Equals(grapheme, singleChar, StringComparison.CurrentCulture)) sw.WriteLine("{0} = {1} (Ordinal): {2}", grapheme, singleChar, String.Equals(grapheme, singleChar, StringComparison.Ordinal)) sw.WriteLine("{0} = {1} (Normalized Ordinal): {2}", grapheme, singleChar, String.Equals(grapheme.Normalize(), singleChar.Normalize(), StringComparison.Ordinal)) sw.Close() End Sub End Module ' The example produces the following output: ' ä ' ä ' ä = ä (Culture-sensitive): True ' ä = ä (Ordinal): False ' ä = ä (Normalized Ordinal): TrueEen Unicode-aanvullend codepunt (een surrogaatpaar) wordt vertegenwoordigd door een Char object waarvan het codepunt een hoog surrogaat is, gevolgd door een Char object waarvan het codepunt een laag surrogaat is. De code-eenheden van hoge surrogaten variëren van U+D800 tot U+DBFF. De code-eenheden van lage surrogaates liggen tussen U+DC00 en U+DFFF. Surrogaatparen worden gebruikt om tekens in de 16 Unicode-aanvullende vlakken weer te geven. In het volgende voorbeeld wordt er een surrogaatteken gemaakt en doorgegeven aan de Char.IsSurrogatePair(Char, Char)-methode om te bepalen of het om een surrogaatpaar gaat.
string surrogate = "\uD800\uDC03"; for (int ctr = 0; ctr < surrogate.Length; ctr++) Console.Write($"U+{(ushort)surrogate[ctr]:X2} "); Console.WriteLine(); Console.WriteLine($" Is Surrogate Pair: {Char.IsSurrogatePair(surrogate[0], surrogate[1])}"); // The example displays the following output: // U+D800 U+DC03 // Is Surrogate Pair: Trueopen System let surrogate = "\uD800\uDC03" for i = 0 to surrogate.Length - 1 do printf $"U+{uint16 surrogate[i]:X2} " printfn $"\n Is Surrogate Pair: {Char.IsSurrogatePair(surrogate[0], surrogate[1])}" // The example displays the following output: // U+D800 U+DC03 // Is Surrogate Pair: TrueModule Example20 Public Sub Main() Dim surrogate As String = ChrW(&HD800) + ChrW(&HDC03) For ctr As Integer = 0 To surrogate.Length - 1 Console.Write("U+{0:X2} ", Convert.ToUInt16(surrogate(ctr))) Next Console.WriteLine() Console.WriteLine(" Is Surrogate Pair: {0}", Char.IsSurrogatePair(surrogate(0), surrogate(1))) End Sub End Module ' The example displays the following output: ' U+D800 U+DC03 ' Is Surrogate Pair: True
De Unicode-standaard
Tekens in een tekenreeks worden vertegenwoordigd door UTF-16 gecodeerde code-eenheden, die overeenkomen met Char waarden.
Elk teken in een tekenreeks heeft een bijbehorende Unicode-tekencategorie, die wordt weergegeven in .NET door de UnicodeCategory opsomming. De categorie van een teken of een surrogaatpaar kan worden bepaald door de CharUnicodeInfo.GetUnicodeCategory-methode aan te roepen.
.NET onderhoudt een eigen tabel met tekens en de bijbehorende categorieën, waardoor een specifieke versie van een .NET-implementatie die op verschillende platforms wordt uitgevoerd, identieke tekencategoriegegevens retourneert. Op alle .NET-versies en op alle besturingssysteemplatforms wordt informatie over tekencategorie verstrekt door de Unicode-tekendatabase.
De volgende tabel bevat .NET-versies en de versies van de Unicode Standard waarop hun tekencategorieën zijn gebaseerd.
| .NET-versie | Versie van de Unicode-standaard |
|---|---|
| .NET Framework 1.1 | Unicode Standard, versie 4.0.0 |
| .NET Framework 2.0 | Unicode Standard, versie 5.0.0 |
| .NET Framework 3.5 | Unicode Standard, versie 5.0.0 |
| .NET Framework 4 | Unicode Standard, versie 5.0.0 |
| .NET Framework 4.5 | Unicode Standard, versie 6.3.0 |
| .NET Framework 4.5.1 | Unicode Standard, versie 6.3.0 |
| .NET Framework 4.5.2 | Unicode Standard, versie 6.3.0 |
| .NET framework 4.6 | Unicode Standard, versie 6.3.0 |
| .NET Framework 4.6.1 | Unicode Standard, versie 6.3.0 |
| .NET Framework 4.6.2 en latere versies | Unicode Standard, versie 8.0.0 |
| .NET Core 2.1 | Unicode Standard, versie 8.0.0 |
| .NET Core 3.1 | Unicode Standard, versie 11.0.0 |
| .NET 5 | Unicode Standard, versie 13.0.0 |
Daarnaast biedt .NET ondersteuning voor tekenreeksvergelijking en sortering op basis van de Unicode-standaard. Vanaf .NET Framework 4.5 die wordt uitgevoerd op Windows 8 en latere versies van het Windows-besturingssysteem, delegeert de runtime tekenreeksvergelijkings- en sorteerbewerkingen naar het besturingssysteem. Op .NET Core en .NET 5+ worden tekenreeksvergelijkings- en sorteergegevens verstrekt door International Components voor Unicode-bibliotheken (behalve in Windows-versies vóór windows 10 mei 2019 Update). De volgende tabel bevat de versies van .NET en de versies van de Unicode Standard waarop tekenvergelijking en sortering zijn gebaseerd.
| .NET-versie | Versie van de Unicode-standaard |
|---|---|
| .NET Framework 4.5 en hoger in Windows 7 | Unicode Standard, versie 5.0.0 |
| .NET Framework 4.5 en hoger op Windows 8- en hoger windows-besturingssystemen | Unicode Standard, versie 6.3.0 |
| .NET Core en .NET 5+ | Is afhankelijk van de versie van de Unicode Standard die wordt ondersteund door het onderliggende besturingssysteem. |
Ingesloten null-tekens
In .NET kan een String object ingesloten null-tekens bevatten, die tellen als onderdeel van de lengte van de tekenreeks. In sommige talen, zoals C en C++, geeft een null-teken echter het einde van een tekenreeks aan; het wordt niet beschouwd als een deel van de tekenreeks en wordt niet meegeteld als onderdeel van de lengte van de tekenreeks. Dit betekent dat de volgende algemene veronderstellingen die C- en C++-programmeurs of C- of C++-bibliotheken mogelijk maken over strings, niet noodzakelijkerwijs geldig zijn wanneer ze worden toegepast op String objecten.
De waarde die door de
strlenofwcslenfuncties wordt geretourneerd, is niet noodzakelijkerwijs gelijk aan String.Length.De tekenreeks die door de
strcpy_sofwcscpy_sfuncties is gemaakt, is niet noodzakelijkerwijs identiek aan de tekenreeks die wordt gekopieerd.
U moet ervoor zorgen dat systeemeigen C- en C++-code waarmee objecten worden geïnstitueerd String en code die wordt doorgegeven String via platformaanroep, niet ervan uitgaat dat een ingesloten null-teken het einde van de tekenreeks markeert.
Ingesloten null-tekens in een tekenreeks worden ook anders behandeld wanneer een tekenreeks wordt gesorteerd (of vergeleken) en wanneer een tekenreeks wordt doorzocht. Null-tekens worden genegeerd bij het uitvoeren van cultuurspecifieke vergelijkingen tussen twee tekenreeksen, inclusief vergelijkingen met behulp van de invariante cultuur. Ze worden alleen beschouwd voor ordinale of hoofdletterongevoelige ordinale vergelijkingen. Aan de andere kant worden ingesloten null-tekens altijd overwogen bij het zoeken naar een tekenreeks met methoden zoals Contains, StartsWithen IndexOf.
Tekenreeksen en indexen
Een index is de positie van een Char object (geen Unicode-teken) in een String. Een index is een op nul gebaseerd, niet-negatief getal dat begint vanaf de eerste positie in de tekenreeks, die de indexpositie nul is. Een aantal zoekmethoden, zoals IndexOf en LastIndexOf, retourneren de index van een teken of subtekenreeks in de tekenreeksinstantie.
Met Chars[Int32] de eigenschap kunt u afzonderlijke Char objecten openen op basis van hun indexpositie in de tekenreeks. Omdat de Chars[Int32] eigenschap de standaardeigenschap (in Visual Basic) of de indexeerfunctie (in C# en F#) is, hebt u toegang tot de afzonderlijke Char objecten in een tekenreeks met behulp van code zoals hieronder. Met deze code wordt gezocht naar witruimte of leestekens in een tekenreeks om te bepalen hoeveel woorden de tekenreeks bevat.
string s1 = "This string consists of a single short sentence.";
int nWords = 0;
s1 = s1.Trim();
for (int ctr = 0; ctr < s1.Length; ctr++) {
if (Char.IsPunctuation(s1[ctr]) | Char.IsWhiteSpace(s1[ctr]))
nWords++;
}
Console.WriteLine($"""
The sentence
{s1}
has {nWords} words.
""");
// The example displays the following output:
// The sentence
// This string consists of a single short sentence.
// has 8 words.
let s1 = "This string consists of a single short sentence."
let mutable nWords = 0
for i = 0 to s1.Length - 1 do
if Char.IsPunctuation s1[i] || Char.IsWhiteSpace s1[i] then
nWords <- nWords + 1
printfn $"The sentence\n {s1}\nhas {nWords} words."
// The example displays the following output:
// The sentence
// This string consists of a single short sentence.
// has 8 words.
Module Example12
Public Sub Main()
Dim s1 As String = "This string consists of a single short sentence."
Dim nWords As Integer = 0
s1 = s1.Trim()
For ctr As Integer = 0 To s1.Length - 1
If Char.IsPunctuation(s1(ctr)) Or Char.IsWhiteSpace(s1(ctr)) Then
nWords += 1
End If
Next
Console.WriteLine("The sentence{2} {0}{2}has {1} words.",
s1, nWords, vbCrLf)
End Sub
End Module
' The example displays the following output:
' The sentence
' This string consists of a single short sentence.
' has 8 words.
Omdat de String klasse de IEnumerable interface implementeert, kunt u ook door de Char objecten in een tekenreeks itereren met behulp van een foreach constructie, zoals het volgende voorbeeld laat zien.
string s1 = "This string consists of a single short sentence.";
int nWords = 0;
s1 = s1.Trim();
foreach (var ch in s1) {
if (Char.IsPunctuation(ch) | Char.IsWhiteSpace(ch))
nWords++;
}
Console.WriteLine($"""
The sentence
{s1}
has {nWords} words.
""");
// The example displays the following output:
// The sentence
// This string consists of a single short sentence.
// has 8 words.
let s1 = "This string consists of a single short sentence."
let mutable nWords = 0
for ch in s1 do
if Char.IsPunctuation ch || Char.IsWhiteSpace ch then
nWords <- nWords + 1
printfn $"The sentence\n {s1}\nhas {nWords} words."
// The example displays the following output:
// The sentence
// This string consists of a single short sentence.
// has 8 words.
Module Example13
Public Sub Main()
Dim s1 As String = "This string consists of a single short sentence."
Dim nWords As Integer = 0
s1 = s1.Trim()
For Each ch In s1
If Char.IsPunctuation(ch) Or Char.IsWhiteSpace(ch) Then
nWords += 1
End If
Next
Console.WriteLine("The sentence{2} {0}{2}has {1} words.",
s1, nWords, vbCrLf)
End Sub
End Module
' The example displays the following output:
' The sentence
' This string consists of a single short sentence.
' has 8 words.
Opeenvolgende indexwaarden komen mogelijk niet overeen met opeenvolgende Unicode-tekens, omdat een Unicode-teken kan worden gecodeerd als meer dan één Char object. Een tekenreeks kan met name teksteenheden met meerdere tekens bevatten die worden gevormd door een basisteken, gevolgd door een of meer combinaties van tekens of door surrogaatparen. Als u wilt werken met Unicode-tekens in plaats van Char objecten, gebruikt u de System.Globalization.StringInfo en TextElementEnumerator klassen of de String.EnumerateRunes methode en de Rune struct. In het volgende voorbeeld ziet u het verschil tussen code die werkt met Char objecten en code die met Unicode-tekens werkt. Hiermee wordt het aantal tekens of tekstelementen in elk woord van een zin vergeleken. De tekenreeks bevat twee reeksen van een basisteken, gevolgd door een combinatieteken.
// First sentence of The Mystery of the Yellow Room, by Leroux.
string opening = "Ce n'est pas sans une certaine émotion que "+
"je commence à raconter ici les aventures " +
"extraordinaires de Joseph Rouletabille.";
// Character counters.
int nChars = 0;
// Objects to store word count.
List<int> chars = new List<int>();
List<int> elements = new List<int>();
foreach (var ch in opening) {
// Skip the ' character.
if (ch == '\u0027') continue;
if (Char.IsWhiteSpace(ch) | (Char.IsPunctuation(ch))) {
chars.Add(nChars);
nChars = 0;
}
else {
nChars++;
}
}
System.Globalization.TextElementEnumerator te =
System.Globalization.StringInfo.GetTextElementEnumerator(opening);
while (te.MoveNext()) {
string s = te.GetTextElement();
// Skip the ' character.
if (s == "\u0027") continue;
if ( String.IsNullOrEmpty(s.Trim()) | (s.Length == 1 && Char.IsPunctuation(Convert.ToChar(s)))) {
elements.Add(nChars);
nChars = 0;
}
else {
nChars++;
}
}
// Display character counts.
Console.WriteLine("{0,6} {1,20} {2,20}",
"Word #", "Char Objects", "Characters");
for (int ctr = 0; ctr < chars.Count; ctr++)
Console.WriteLine("{0,6} {1,20} {2,20}",
ctr, chars[ctr], elements[ctr]);
// The example displays the following output:
// Word # Char Objects Characters
// 0 2 2
// 1 4 4
// 2 3 3
// 3 4 4
// 4 3 3
// 5 8 8
// 6 8 7
// 7 3 3
// 8 2 2
// 9 8 8
// 10 2 1
// 11 8 8
// 12 3 3
// 13 3 3
// 14 9 9
// 15 15 15
// 16 2 2
// 17 6 6
// 18 12 12
open System
open System.Globalization
// First sentence of The Mystery of the Yellow Room, by Leroux.
let opening = "Ce n'est pas sans une certaine émotion que je commence à raconter ici les aventures extraordinaires de Joseph Rouletabille."
// Character counters.
let mutable nChars = 0
// Objects to store word count.
let chars = ResizeArray<int>()
let elements = ResizeArray<int>()
for ch in opening do
// Skip the ' character.
if ch <> '\u0027' then
if Char.IsWhiteSpace ch || Char.IsPunctuation ch then
chars.Add nChars
nChars <- 0
else
nChars <- nChars + 1
let te = StringInfo.GetTextElementEnumerator opening
while te.MoveNext() do
let s = te.GetTextElement()
// Skip the ' character.
if s <> "\u0027" then
if String.IsNullOrEmpty(s.Trim()) || (s.Length = 1 && Char.IsPunctuation(Convert.ToChar s)) then
elements.Add nChars
nChars <- 0
else
nChars <- nChars + 1
// Display character counts.
printfn "%6s %20s %20s" "Word #" "Char Objects " "Characters"
for i = 0 to chars.Count - 1 do
printfn "%6d %20d %20d" i chars[i] elements[i]
// The example displays the following output:
// Word # Char Objects Characters
// 0 2 2
// 1 4 4
// 2 3 3
// 3 4 4
// 4 3 3
// 5 8 8
// 6 8 7
// 7 3 3
// 8 2 2
// 9 8 8
// 10 2 1
// 11 8 8
// 12 3 3
// 13 3 3
// 14 9 9
// 15 15 15
// 16 2 2
// 17 6 6
// 18 12 12
Imports System.Collections.Generic
Imports System.Globalization
Module Example14
Public Sub Main()
' First sentence of The Mystery of the Yellow Room, by Leroux.
Dim opening As String = "Ce n'est pas sans une certaine émotion que " +
"je commence à raconter ici les aventures " +
"extraordinaires de Joseph Rouletabille."
' Character counters.
Dim nChars As Integer = 0
' Objects to store word count.
Dim chars As New List(Of Integer)()
Dim elements As New List(Of Integer)()
For Each ch In opening
' Skip the ' character.
If ch = ChrW(&H27) Then Continue For
If Char.IsWhiteSpace(ch) Or Char.IsPunctuation(ch) Then
chars.Add(nChars)
nChars = 0
Else
nChars += 1
End If
Next
Dim te As TextElementEnumerator = StringInfo.GetTextElementEnumerator(opening)
Do While te.MoveNext()
Dim s As String = te.GetTextElement()
' Skip the ' character.
If s = ChrW(&H27) Then Continue Do
If String.IsNullOrEmpty(s.Trim()) Or (s.Length = 1 AndAlso Char.IsPunctuation(Convert.ToChar(s))) Then
elements.Add(nChars)
nChars = 0
Else
nChars += 1
End If
Loop
' Display character counts.
Console.WriteLine("{0,6} {1,20} {2,20}",
"Word #", "Char Objects", "Characters")
For ctr As Integer = 0 To chars.Count - 1
Console.WriteLine("{0,6} {1,20} {2,20}",
ctr, chars(ctr), elements(ctr))
Next
End Sub
End Module
' The example displays the following output:
' Word # Char Objects Characters
' 0 2 2
' 1 4 4
' 2 3 3
' 3 4 4
' 4 3 3
' 5 8 8
' 6 8 7
' 7 3 3
' 8 2 2
' 9 8 8
' 10 2 1
' 11 8 8
' 12 3 3
' 13 3 3
' 14 9 9
' 15 15 15
' 16 2 2
' 17 6 6
' 18 12 12
Dit voorbeeld werkt met tekstelementen met behulp van de StringInfo.GetTextElementEnumerator methode en de TextElementEnumerator klasse om alle tekstelementen in een tekenreeks op te sommen. U kunt ook een matrix ophalen die de beginindex van elk tekstelement bevat door de methode aan te StringInfo.ParseCombiningCharacters roepen.
Zie Inleiding tot tekencodering in .NET voor meer informatie over het werken met teksteenheden in plaats van afzonderlijke Char waarden.
Null-tekenreeksen en lege tekenreeksen
Een tekenreeks die is gedeclareerd maar waaraan geen waarde is toegewezen, is null. Het proberen methoden op die tekenreeks aan te roepen, genereert een NullReferenceException. Een null-tekenreeks verschilt van een lege tekenreeks, een tekenreeks waarvan de waarde '' is of String.Empty. In sommige gevallen genereert het doorgeven van een null-tekenreeks of een lege tekenreeks als argument in een methodeaanroep een uitzondering. Als u bijvoorbeeld een null-waarde doorgeeft aan de Int32.Parse-methode, wordt een ArgumentNullException opgegooid, en als er een lege tekenreeks wordt doorgegeven, wordt een FormatException opgegooid. In andere gevallen kan een methodeargument een null-tekenreeks of een lege tekenreeks zijn. Als u bijvoorbeeld een IFormattable implementatie voor een klasse opgeeft, wilt u zowel een null-tekenreeks als een lege tekenreeks vergelijken met de algemene notatieaanduiding ('G').
De String klasse bevat de volgende twee handige methoden waarmee u kunt testen of een tekenreeks null of leeg is:
IsNullOrEmpty, waarmee wordt aangegeven of een tekenreeks gelijk
nullis aan of gelijk is aan String.Empty. Met deze methode hoeft u geen code meer te gebruiken, zoals de volgende:if (str == null || str.Equals(String.Empty))if str = null || str.Equals String.Empty thenIf str Is Nothing OrElse str.Equals(String.Empty) ThenIsNullOrWhiteSpace, waarmee wordt aangegeven of een tekenreeks
nullis, gelijk is aan String.Empty, of uitsluitend uit spatietekens bestaat. Met deze methode hoeft u geen code meer te gebruiken, zoals de volgende:if (str == null || str.Equals(String.Empty) || str.Trim().Equals(String.Empty))if str = null || str.Equals String.Empty || str.Trim().Equals String.Empty thenIf str Is Nothing OrElse str.Equals(String.Empty) OrElse str.Trim().Equals(String.Empty) Then
In het volgende voorbeeld wordt de IsNullOrEmpty methode gebruikt in de IFormattable.ToString implementatie van een aangepaste Temperature klasse. De methode ondersteunt de tekenreeksen 'G', 'C', 'F' en 'K'. Als een lege notatietekenreeks of een notatietekenreeks waarvan de waarde null is aan de methode wordt doorgegeven, wordt de waarde gewijzigd in de notatietekenreeks "G".
public string ToString(string format, IFormatProvider provider)
{
if (String.IsNullOrEmpty(format)) format = "G";
if (provider == null) provider = CultureInfo.CurrentCulture;
switch (format.ToUpperInvariant())
{
// Return degrees in Celsius.
case "G":
case "C":
return temp.ToString("F2", provider) + "°C";
// Return degrees in Fahrenheit.
case "F":
return (temp * 9 / 5 + 32).ToString("F2", provider) + "°F";
// Return degrees in Kelvin.
case "K":
return (temp + 273.15).ToString();
default:
throw new FormatException(
String.Format("The {0} format string is not supported.",
format));
}
}
member _.ToString(format: string, provider: IFormatProvider) =
let format =
if String.IsNullOrEmpty format then "G" else format
let provider: IFormatProvider =
if provider = null then CultureInfo.CurrentCulture else provider
match format.ToUpperInvariant() with
// Return degrees in Celsius.
| "G"
| "C" ->
temp.ToString("F2", provider) + "°C"
// Return degrees in Fahrenheit.
| "F" ->
(temp * 9. / 5. + 32.).ToString("F2", provider) + "°F"
// Return degrees in Kelvin.
| "K" ->
(temp + 273.15).ToString()
| _ ->
raise (FormatException(String.Format("The {0} format string is not supported.",format)))
Public Overloads Function ToString(fmt As String, provider As IFormatProvider) As String _
Implements IFormattable.ToString
If String.IsNullOrEmpty(fmt) Then fmt = "G"
If provider Is Nothing Then provider = CultureInfo.CurrentCulture
Select Case fmt.ToUpperInvariant()
' Return degrees in Celsius.
Case "G", "C"
Return temp.ToString("F2", provider) + "°C"
' Return degrees in Fahrenheit.
Case "F"
Return (temp * 9 / 5 + 32).ToString("F2", provider) + "°F"
' Return degrees in Kelvin.
Case "K"
Return (temp + 273.15).ToString()
Case Else
Throw New FormatException(
String.Format("The {0} format string is not supported.",
fmt))
End Select
End Function
Onveranderbaarheid en de klasse StringBuilder
Een String object wordt onveranderbaar genoemd (alleen-lezen), omdat de waarde ervan niet kan worden gewijzigd nadat het is gemaakt. Methoden die een String object lijken te wijzigen, retourneren daadwerkelijk een nieuw String object dat de wijziging bevat.
Omdat tekenreeksen onveranderbaar zijn, kunnen bewerkingsroutines voor tekenreeksen die herhaalde toevoegingen of verwijderingen uitvoeren aan wat een enkele tekenreeks lijkt te zijn, een aanzienlijke prestatiestraf kunnen bepalen. In de volgende code wordt bijvoorbeeld een willekeurige getallengenerator gebruikt om een tekenreeks met 1000 tekens te maken in het bereik van 0x0001 tot 0x052F. Hoewel de code tekenreekssamenvoeging lijkt te gebruiken om een nieuw teken toe te voegen aan de bestaande tekenreeks met de naam str, wordt er daadwerkelijk een nieuw String object gemaakt voor elke samenvoegingsbewerking.
using System;
using System.IO;
using System.Text;
public class Example6
{
public static void Main()
{
Random rnd = new Random();
string str = String.Empty;
StreamWriter sw = new StreamWriter(@".\StringFile.txt",
false, Encoding.Unicode);
for (int ctr = 0; ctr <= 1000; ctr++) {
str += (char)rnd.Next(1, 0x0530);
if (str.Length % 60 == 0)
str += Environment.NewLine;
}
sw.Write(str);
sw.Close();
}
}
open System
open System.IO
open System.Text
do
let rnd = Random()
let mutable str = String.Empty
use sw = new StreamWriter(@".\StringFile.txt", false, Encoding.Unicode)
for _ = 0 to 1000 do
str <- str + (rnd.Next(1, 0x0530) |> char |> string)
if str.Length % 60 = 0 then
str <- str + Environment.NewLine
sw.Write str
Imports System.IO
Imports System.Text
Module Example10
Public Sub Main()
Dim rnd As New Random()
Dim str As String = String.Empty
Dim sw As New StreamWriter(".\StringFile.txt",
False, Encoding.Unicode)
For ctr As Integer = 0 To 1000
str += ChrW(rnd.Next(1, &H530))
If str.Length Mod 60 = 0 Then str += vbCrLf
Next
sw.Write(str)
sw.Close()
End Sub
End Module
U kunt de StringBuilder klasse gebruiken in plaats van de String klasse voor bewerkingen die meerdere wijzigingen aanbrengen in de waarde van een tekenreeks. In tegenstelling tot exemplaren van de String klasse StringBuilder zijn objecten veranderlijk. Wanneer u subtekenreeksen uit een tekenreeks samenvoegt, toevoegt of verwijdert, worden de bewerkingen uitgevoerd op één tekenreeks. Wanneer u klaar bent met het wijzigen van de waarde van een StringBuilder object, kunt u de StringBuilder.ToString methode aanroepen om het te converteren naar een tekenreeks. In het volgende voorbeeld wordt het String object, dat in het vorige voorbeeld werd gebruikt, vervangen door een StringBuilder object om 1000 willekeurige tekens in het bereik van 0x0001 tot 0x052F samen te voegen.
using System;
using System.IO;
using System.Text;
public class Example10
{
public static void Main()
{
Random rnd = new Random();
StringBuilder sb = new StringBuilder();
StreamWriter sw = new StreamWriter(@".\StringFile.txt",
false, Encoding.Unicode);
for (int ctr = 0; ctr <= 1000; ctr++) {
sb.Append((char)rnd.Next(1, 0x0530));
if (sb.Length % 60 == 0)
sb.AppendLine();
}
sw.Write(sb.ToString());
sw.Close();
}
}
open System
open System.IO
open System.Text
do
let rnd = Random()
let sb = StringBuilder()
use sw = new StreamWriter(@".\StringFile.txt", false, Encoding.Unicode)
for _ = 0 to 1000 do
sb.Append(rnd.Next(1, 0x0530) |> char) |> ignore
if sb.Length % 60 = 0 then
sb.AppendLine() |> ignore
sw.Write(string sb)
Imports System.IO
Imports System.Text
Module Example11
Public Sub Main()
Dim rnd As New Random()
Dim sb As New StringBuilder()
Dim sw As New StreamWriter(".\StringFile.txt",
False, Encoding.Unicode)
For ctr As Integer = 0 To 1000
sb.Append(ChrW(rnd.Next(1, &H530)))
If sb.Length Mod 60 = 0 Then sb.AppendLine()
Next
sw.Write(sb.ToString())
sw.Close()
End Sub
End Module
Ordinale versus cultuurgevoelige bewerkingen
Leden van de String klasse voeren ordinale of cultuurgevoelige (taalkundige) bewerkingen uit op een String object. Een rangtelbewerking werkt op de numerieke waarde van elk Char object. Een cultuurgevoelige bewerking werkt op de waarde van het String object en houdt rekening met cultuurspecifieke behuizings-, sorteer-, opmaak- en parseringsregels. Cultuurgevoelige bewerkingen worden uitgevoerd in de context van een expliciet gedeclareerde cultuur of de impliciete huidige cultuur. De twee soorten bewerkingen kunnen zeer verschillende resultaten opleveren wanneer ze op dezelfde string worden uitgevoerd.
.NET biedt ook ondersteuning voor cultuurongevoelige taalreeksbewerkingen door gebruik te maken van de invariante cultuur (CultureInfo.InvariantCulture), die losjes is gebaseerd op de cultuurinstellingen van de Engelse taal onafhankelijk van de regio. In tegenstelling tot andere System.Globalization.CultureInfo instellingen blijven de instellingen van de invariante cultuur gegarandeerd consistent op één computer, van systeem tot systeem en in verschillende versies van .NET. De invariante cultuur kan worden gezien als een soort zwarte doos die stabiliteit van tekenreeksvergelijkingen en ordenen in alle culturen garandeert.
Belangrijk
Als uw toepassing een beveiligingsbeslissing neemt over een symbolische id, zoals een bestandsnaam of een benoemde pijp, of over persistente gegevens, zoals de op tekst gebaseerde gegevens in een XML-bestand, moet de bewerking een ordinale vergelijking gebruiken in plaats van een cultuurgevoelige vergelijking. Dit komt doordat een cultuurgevoelige vergelijking verschillende resultaten kan opleveren, afhankelijk van de cultuur die van kracht is, terwijl een rangtelvergelijking alleen afhankelijk is van de binaire waarde van de vergeleken tekens.
Belangrijk
De meeste methoden die tekenreeksbewerkingen uitvoeren, bevatten een overbelasting met een parameter van het type StringComparison, waarmee u kunt opgeven of de methode een ordinale of cultuurgevoelige bewerking uitvoert. Over het algemeen moet u deze overbelasting aanroepen om de intentie van uw methode-aanroep duidelijk te maken. Voor aanbevolen procedures en richtlijnen voor het gebruik van ordinale en cultuurgevoelige bewerkingen op tekenreeksen, zie Aanbevolen procedures voor het gebruik van tekenreeksen.
Bewerkingen voor lettertype-aanpassingen, ontleden en opmaken, evenals vergelijking en sorteren, en testen op gelijkheid kunnen ordinaal of cultuurgevoelig zijn. In de volgende secties wordt elke bewerkingscategorie besproken.
Aanbeveling
U moet altijd een overbelasting van een methode aanroepen die de intentie van uw methode-aanroep duidelijk maakt. In plaats van de Compare(String, String) methode bijvoorbeeld aan te roepen om een cultuurgevoelige vergelijking van twee tekenreeksen uit te voeren met behulp van de conventies van de huidige cultuur, moet u de Compare(String, String, StringComparison) methode aanroepen met een waarde voor StringComparison.CurrentCulture het comparisonType argument. Zie Aanbevolen procedures voor het gebruik van tekenreeksen voor meer informatie.
U kunt de sorteergewichttabellen, een set tekstbestanden die informatie bevatten over de tekengewichten die worden gebruikt in sorteer- en vergelijkingsbewerkingen, downloaden via de volgende koppelingen:
- Windows (.NET Framework en .NET Core): Gewichtstabellen sorteren
- Windows 10 mei 2019 Update of hoger (.NET 5+) en Linux en macOS (.NET Core en .NET 5+): Standaardtabel unicode-sorteringselement
Hoofdlettergebruik
Hoofdletterregels bepalen hoe het hoofdlettergebruik van een Unicode-teken moet worden gewijzigd; bijvoorbeeld van kleine letters naar hoofdletters. Vaak wordt een behuizingsbewerking uitgevoerd vóór een tekenreeksvergelijking. Een tekenreeks kan bijvoorbeeld worden geconverteerd naar hoofdletters, zodat deze kan worden vergeleken met een andere tekenreeks in hoofdletters. U kunt de tekens in een tekenreeks converteren naar kleine letters door de ToLower of ToLowerInvariant methode aan te roepen en u kunt ze converteren naar hoofdletters door de ToUpper of ToUpperInvariant methode aan te roepen. Daarnaast kunt u de TextInfo.ToTitleCase methode gebruiken om een tekenreeks te converteren naar een titelcase.
Notitie
.NET Core wordt alleen uitgevoerd op Linux- en macOS-systemen: het sorteringsgedrag voor de C- en Posix-culturen is altijd hoofdlettergevoelig omdat deze culturen niet de verwachte Unicode-sorteringsvolgorde gebruiken. U wordt aangeraden een andere cultuur dan C of Posix te gebruiken voor het uitvoeren van cultuurgevoelige, hoofdletterongevoelige sorteerbewerkingen.
Casingbewerkingen kunnen gebaseerd zijn op de regels van de huidige cultuur, een opgegeven cultuur of de invariante cultuur. Omdat casetoewijzingen kunnen variëren, afhankelijk van de gebruikte cultuur, kan het resultaat van casingbewerkingen variëren op basis van cultuur. De werkelijke verschillen in behuizing zijn van drie soorten:
Verschillen in de toewijzing van LATIJNSE HOOFDLETTER I (U+0049), LATIJNSE KLEINE LETTER I (U+0069), LATIJNSE HOOFDLETTER I MET PUNT BOVEN (U+0130) en LATIJNSE KLEINE LETTER I ZONDER PUNT (U+0131). In de tr-TR-culturen (Turks (Turkije)) en az-Latn-AZ (Azerbeidzjaans, Latijns) en in de tr-, az- en az-Latn-neutrale culturen is het kleine equivalent van LATIJNSE HOOFDLETTER I LATIJNSE KLEINE LETTER PUNTLOZE I en het hoofdletter equivalent van LATIJNSE KLEINE LETTER I is LATIJNSE HOOFDLETTER I MET PUNT HIERBOVEN. In alle andere culturen, waaronder de invariante cultuur, zijn de LATIJNSE KLEINE LETTER I en de LATIJNSE HOOFDLETTER I elkaars kleine en hoofdletterequivalenten.
In het volgende voorbeeld ziet u hoe een tekenreeksvergelijking die is ontworpen om toegang tot het bestandssysteem te voorkomen, kan mislukken als deze afhankelijk is van een cultuurgevoelige casingvergelijking. (De casingconventies van de invariante cultuur moeten worden gebruikt.)
using System; using System.Globalization; using System.Threading; public class Example1 { const string disallowed = "file"; public static void Main() { IsAccessAllowed(@"FILE:\\\c:\users\user001\documents\FinancialInfo.txt"); } private static void IsAccessAllowed(String resource) { CultureInfo[] cultures = { CultureInfo.CreateSpecificCulture("en-US"), CultureInfo.CreateSpecificCulture("tr-TR") }; String scheme = null; int index = resource.IndexOfAny( new Char[] { '\\', '/' } ); if (index > 0) scheme = resource.Substring(0, index - 1); // Change the current culture and perform the comparison. foreach (var culture in cultures) { Thread.CurrentThread.CurrentCulture = culture; Console.WriteLine($"Culture: {CultureInfo.CurrentCulture.DisplayName}"); Console.WriteLine(resource); Console.WriteLine($"Access allowed: {! String.Equals(disallowed, scheme, StringComparison.CurrentCultureIgnoreCase)}"); Console.WriteLine(); } } } // The example displays the following output: // Culture: English (United States) // FILE:\\\c:\users\user001\documents\FinancialInfo.txt // Access allowed: False // // Culture: Turkish (Turkey) // FILE:\\\c:\users\user001\documents\FinancialInfo.txt // Access allowed: Trueopen System open System.Globalization open System.Threading let disallowed = "file" let isAccessAllowed (resource: string) = let cultures = [| CultureInfo.CreateSpecificCulture "en-US" CultureInfo.CreateSpecificCulture "tr-TR" |] let index = resource.IndexOfAny [| '\\'; '/' |] let scheme = if index > 0 then resource.Substring(0, index - 1) else null // Change the current culture and perform the comparison. for culture in cultures do Thread.CurrentThread.CurrentCulture <- culture printfn $"Culture: {CultureInfo.CurrentCulture.DisplayName}" printfn $"{resource}" printfn $"Access allowed: {String.Equals(disallowed, scheme, StringComparison.CurrentCultureIgnoreCase) |> not}" printfn "" isAccessAllowed @"FILE:\\\c:\users\user001\documents\FinancialInfo.txt" // The example displays the following output: // Culture: English (United States) // FILE:\\\c:\users\user001\documents\FinancialInfo.txt // Access allowed: False // // Culture: Turkish (Turkey) // FILE:\\\c:\users\user001\documents\FinancialInfo.txt // Access allowed: TrueImports System.Globalization Imports System.Threading Module Example2 Const disallowed = "file" Public Sub Main() IsAccessAllowed("FILE:\\\c:\users\user001\documents\FinancialInfo.txt") End Sub Private Sub IsAccessAllowed(resource As String) Dim cultures() As CultureInfo = {CultureInfo.CreateSpecificCulture("en-US"), CultureInfo.CreateSpecificCulture("tr-TR")} Dim scheme As String = Nothing Dim index As Integer = resource.IndexOfAny({"\"c, "/"c}) If index > 0 Then scheme = resource.Substring(0, index - 1) ' Change the current culture and perform the comparison. For Each culture In cultures Thread.CurrentThread.CurrentCulture = culture Console.WriteLine("Culture: {0}", CultureInfo.CurrentCulture.DisplayName) Console.WriteLine(resource) Console.WriteLine("Access allowed: {0}", Not String.Equals(disallowed, scheme, StringComparison.CurrentCultureIgnoreCase)) Console.WriteLine() Next End Sub End Module ' The example displays the following output: ' Culture: English (United States) ' FILE:\\\c:\users\user001\documents\FinancialInfo.txt ' Access allowed: False ' ' Culture: Turkish (Turkey) ' FILE:\\\c:\users\user001\documents\FinancialInfo.txt ' Access allowed: TrueVerschillen in geval van toewijzingen tussen de invariante cultuur en alle andere culturen. In deze gevallen retourneert het gebruik van de hoofdletterregels van de invariante cultuur, om een teken in hoofdletters of kleine letters te veranderen, hetzelfde teken. Voor alle andere culturen retourneert het een ander karakter. Sommige van de betrokken tekens worden weergegeven in de volgende tabel.
Teken Indien gewijzigd naar Retouren MICRON-TEKEN (U+00B5) Hoofdletters GRIEKSE HOOFDLETTER MU (U+-39C) DE LATIJNSE HOOFDLETTER I MET PUNT BOVEN (U+0130) Kleine letters LATIJNSE KLEINE LETTER I (U+0069) LATIJNSE KLEINE LETTER i zonder punt (U+0131) Hoofdletters LATIJNSE HOOFDLETTER I (U+0049) LATIJNSE KLEINE LETTER LANGE S (U+017F) Hoofdletters LATIJNSE HOOFDLETTER S (U+0053) LATIJNSE HOOFDLETTER D MET KLEINE LETTER Z MET CARON (U+01C5) Kleine letters LATIJNSE KLEINE LETTER DZ MET CARON (U+01C6) COMBINATIE VAN GRIEKSE YPOGEGRAMMENI (U+0345) Hoofdletters GRIEKSE HOOFDLETTER IOTA (U+0399) Verschillen in casetoewijzingen van paren tussen twee letters in het ASCII-tekenbereik. In de meeste culturen is een tweeletters-combinatie met gemengde hoofd- en kleine letters gelijk aan het equivalente paar van twee hoofdletters of twee kleine letters. Dit geldt niet voor de volgende twee-letterige paren in de volgende culturen, omdat ze telkens worden vergeleken met een digraaf.
- "lJ" en "nJ" in de hr-HR -cultuur (Kroatisch (Kroatië)).
- "cH" in de cs-CZ (Tsjechische (Tsjechië)) en sk-SK (Slowaakse (Slowakije)) culturen.
- "aA" in de da-DK -cultuur (Deens (Denemarken)).
- "cS", "dZ", "dZS", "nY", "sZ", "tY" en "zS" in de hu-HU (Hongaarse (Hongarije) cultuur.
- "cH" en "lL" in de es-ES_tradnl (Spaans (Spanje, traditionele sortering)) cultuur.
- "cH", "gI", "kH", "nG", "nH", "pH", "qU'", "tH" en "tR" in de vi-VN (Vietnamese (Vietnam))-cultuur.
Het is echter ongebruikelijk om een situatie tegen te komen waarin een cultuurgevoelige vergelijking van deze paren problemen veroorzaakt, omdat deze paren ongebruikelijk zijn in vaste tekenreeksen of id's.
In het volgende voorbeeld ziet u enkele van de verschillen in hoofdletterregels tussen verschillende culturen bij het omzetten van tekenreeksen naar hoofdletters.
using System;
using System.Globalization;
using System.IO;
public class Example
{
public static void Main()
{
StreamWriter sw = new StreamWriter(@".\case.txt");
string[] words = { "file", "sıfır", "Dženana" };
CultureInfo[] cultures = { CultureInfo.InvariantCulture,
new CultureInfo("en-US"),
new CultureInfo("tr-TR") };
foreach (var word in words) {
sw.WriteLine("{0}:", word);
foreach (var culture in cultures) {
string name = String.IsNullOrEmpty(culture.Name) ?
"Invariant" : culture.Name;
string upperWord = word.ToUpper(culture);
sw.WriteLine(" {0,10}: {1,7} {2, 38}", name,
upperWord, ShowHexValue(upperWord));
}
sw.WriteLine();
}
sw.Close();
}
private static string ShowHexValue(string s)
{
string retval = null;
foreach (var ch in s) {
byte[] bytes = BitConverter.GetBytes(ch);
retval += String.Format("{0:X2} {1:X2} ", bytes[1], bytes[0]);
}
return retval;
}
}
// The example displays the following output:
// file:
// Invariant: FILE 00 46 00 49 00 4C 00 45
// en-US: FILE 00 46 00 49 00 4C 00 45
// tr-TR: FİLE 00 46 01 30 00 4C 00 45
//
// sıfır:
// Invariant: SıFıR 00 53 01 31 00 46 01 31 00 52
// en-US: SIFIR 00 53 00 49 00 46 00 49 00 52
// tr-TR: SIFIR 00 53 00 49 00 46 00 49 00 52
//
// Dženana:
// Invariant: DžENANA 01 C5 00 45 00 4E 00 41 00 4E 00 41
// en-US: DŽENANA 01 C4 00 45 00 4E 00 41 00 4E 00 41
// tr-TR: DŽENANA 01 C4 00 45 00 4E 00 41 00 4E 00 41
open System
open System.Globalization
open System.IO
let showHexValue (s: string) =
let mutable retval = ""
for ch in s do
let bytes = BitConverter.GetBytes ch
retval <- retval + String.Format("{0:X2} {1:X2} ", bytes[1], bytes[0])
retval
do
use sw = new StreamWriter(@".\case.txt")
let words = [| "file"; "sıfır"; "Dženana" |]
let cultures =
[| CultureInfo.InvariantCulture
CultureInfo "en-US"
CultureInfo "tr-TR" |]
for word in words do
sw.WriteLine("{0}:", word)
for culture in cultures do
let name =
if String.IsNullOrEmpty culture.Name then "Invariant" else culture.Name
let upperWord = word.ToUpper culture
sw.WriteLine(" {0,10}: {1,7} {2, 38}", name, upperWord, showHexValue upperWord)
sw.WriteLine()
sw.Close()
// The example displays the following output:
// file:
// Invariant: FILE 00 46 00 49 00 4C 00 45
// en-US: FILE 00 46 00 49 00 4C 00 45
// tr-TR: FİLE 00 46 01 30 00 4C 00 45
//
// sıfır:
// Invariant: SıFıR 00 53 01 31 00 46 01 31 00 52
// en-US: SIFIR 00 53 00 49 00 46 00 49 00 52
// tr-TR: SIFIR 00 53 00 49 00 46 00 49 00 52
//
// Dženana:
// Invariant: DžENANA 01 C5 00 45 00 4E 00 41 00 4E 00 41
// en-US: DŽENANA 01 C4 00 45 00 4E 00 41 00 4E 00 41
// tr-TR: DŽENANA 01 C4 00 45 00 4E 00 41 00 4E 00 41
Imports System.Globalization
Imports System.IO
Module Example1
Public Sub Main()
Dim sw As New StreamWriter(".\case.txt")
Dim words As String() = {"file", "sıfır", "Dženana"}
Dim cultures() As CultureInfo = {CultureInfo.InvariantCulture,
New CultureInfo("en-US"),
New CultureInfo("tr-TR")}
For Each word In words
sw.WriteLine("{0}:", word)
For Each culture In cultures
Dim name As String = If(String.IsNullOrEmpty(culture.Name),
"Invariant", culture.Name)
Dim upperWord As String = word.ToUpper(culture)
sw.WriteLine(" {0,10}: {1,7} {2, 38}", name,
upperWord, ShowHexValue(upperWord))
Next
sw.WriteLine()
Next
sw.Close()
End Sub
Private Function ShowHexValue(s As String) As String
Dim retval As String = Nothing
For Each ch In s
Dim bytes() As Byte = BitConverter.GetBytes(ch)
retval += String.Format("{0:X2} {1:X2} ", bytes(1), bytes(0))
Next
Return retval
End Function
End Module
' The example displays the following output:
' file:
' Invariant: FILE 00 46 00 49 00 4C 00 45
' en-US: FILE 00 46 00 49 00 4C 00 45
' tr-TR: FİLE 00 46 01 30 00 4C 00 45
'
' sıfır:
' Invariant: SıFıR 00 53 01 31 00 46 01 31 00 52
' en-US: SIFIR 00 53 00 49 00 46 00 49 00 52
' tr-TR: SIFIR 00 53 00 49 00 46 00 49 00 52
'
' Dženana:
' Invariant: DžENANA 01 C5 00 45 00 4E 00 41 00 4E 00 41
' en-US: DŽENANA 01 C4 00 45 00 4E 00 41 00 4E 00 41
' tr-TR: DŽENANA 01 C4 00 45 00 4E 00 41 00 4E 00 41
Parseren en opmaken
Opmaak en parsering zijn inverse bewerkingen. Met opmaakregels wordt bepaald hoe u een waarde, zoals een datum en tijd of een getal, converteert naar de tekenreeksweergave, terwijl bij het parseren van regels wordt bepaald hoe u een tekenreeksweergave converteert naar een waarde zoals een datum en tijd. Zowel opmaak- als parseringsregels zijn afhankelijk van culturele conventies. In het volgende voorbeeld ziet u de dubbelzinnigheid die zich kan voordoen bij het interpreteren van een cultuurspecifieke datumtekenreeks. Zonder de conventies van de cultuur die is gebruikt om een datumtekenreeks te produceren, is het niet mogelijk om te weten of 03/01/2011, 1-3-2011 en 01-03-2011 3 januari 2011 of 1 maart 2011 vertegenwoordigen.
using System;
using System.Globalization;
public class Example9
{
public static void Main()
{
DateTime date = new DateTime(2011, 3, 1);
CultureInfo[] cultures = { CultureInfo.InvariantCulture,
new CultureInfo("en-US"),
new CultureInfo("fr-FR") };
foreach (var culture in cultures)
Console.WriteLine("{0,-12} {1}", String.IsNullOrEmpty(culture.Name) ?
"Invariant" : culture.Name,
date.ToString("d", culture));
}
}
// The example displays the following output:
// Invariant 03/01/2011
// en-US 3/1/2011
// fr-FR 01/03/2011
open System
open System.Globalization
let date = DateTime(2011, 3, 1)
let cultures =
[| CultureInfo.InvariantCulture
CultureInfo "en-US"
CultureInfo "fr-FR" |]
for culture in cultures do
printfn $"""{(if String.IsNullOrEmpty culture.Name then "Invariant" else culture.Name),-12} {date.ToString("d", culture)}"""
// The example displays the following output:
// Invariant 03/01/2011
// en-US 3/1/2011
// fr-FR 01/03/2011
Imports System.Globalization
Module Example8
Public Sub Main()
Dim dat As Date = #3/1/2011#
Dim cultures() As CultureInfo = {CultureInfo.InvariantCulture,
New CultureInfo("en-US"),
New CultureInfo("fr-FR")}
For Each culture In cultures
Console.WriteLine("{0,-12} {1}", If(String.IsNullOrEmpty(culture.Name),
"Invariant", culture.Name),
dat.ToString("d", culture))
Next
End Sub
End Module
' The example displays the following output:
' Invariant 03/01/2011
' en-US 3/1/2011
' fr-FR 01/03/2011
Zoals in het volgende voorbeeld wordt weergegeven, kan één tekenreeks verschillende datums produceren, afhankelijk van de cultuur waarvan de conventies worden gebruikt in de parseringsbewerking.
using System;
using System.Globalization;
public class Example15
{
public static void Main()
{
string dateString = "07/10/2011";
CultureInfo[] cultures = { CultureInfo.InvariantCulture,
CultureInfo.CreateSpecificCulture("en-GB"),
CultureInfo.CreateSpecificCulture("en-US") };
Console.WriteLine("{0,-12} {1,10} {2,8} {3,8}\n", "Date String", "Culture",
"Month", "Day");
foreach (var culture in cultures) {
DateTime date = DateTime.Parse(dateString, culture);
Console.WriteLine("{0,-12} {1,10} {2,8} {3,8}", dateString,
String.IsNullOrEmpty(culture.Name) ?
"Invariant" : culture.Name,
date.Month, date.Day);
}
}
}
// The example displays the following output:
// Date String Culture Month Day
//
// 07/10/2011 Invariant 7 10
// 07/10/2011 en-GB 10 7
// 07/10/2011 en-US 7 10
open System
open System.Globalization
let dateString = "07/10/2011"
let cultures =
[| CultureInfo.InvariantCulture
CultureInfo.CreateSpecificCulture "en-GB"
CultureInfo.CreateSpecificCulture "en-US" |]
printfn $"""{"Date String",-12} {"Culture",10} {"Month",8} {"Day",8}\n"""
for culture in cultures do
let date = DateTime.Parse(dateString, culture)
printfn $"""{dateString,-12} {(if String.IsNullOrEmpty culture.Name then "Invariant" else culture.Name),10} {date.Month,8} {date.Day,8}"""
// The example displays the following output:
// Date String Culture Month Day
//
// 07/10/2011 Invariant 7 10
// 07/10/2011 en-GB 10 7
// 07/10/2011 en-US 7 10
Imports System.Globalization
Module Example18
Public Sub Main()
Dim dateString As String = "07/10/2011"
Dim cultures() As CultureInfo = {CultureInfo.InvariantCulture,
CultureInfo.CreateSpecificCulture("en-GB"),
CultureInfo.CreateSpecificCulture("en-US")}
Console.WriteLine("{0,-12} {1,10} {2,8} {3,8}", "Date String", "Culture",
"Month", "Day")
Console.WriteLine()
For Each culture In cultures
Dim dat As Date = DateTime.Parse(dateString, culture)
Console.WriteLine("{0,-12} {1,10} {2,8} {3,8}", dateString,
If(String.IsNullOrEmpty(culture.Name),
"Invariant", culture.Name),
dat.Month, dat.Day)
Next
End Sub
End Module
' The example displays the following output:
' Date String Culture Month Day
'
' 07/10/2011 Invariant 7 10
' 07/10/2011 en-GB 10 7
' 07/10/2011 en-US 7 10
Tekenreeksvergelijking en -sortering
Conventies voor het vergelijken en sorteren van tekenreeksen verschillen van cultuur tot cultuur. De sorteervolgorde kan bijvoorbeeld zijn gebaseerd op fonetiek of op de visuele weergave van tekens. In de Oost-Aziatische talen worden tekens gesorteerd op de streken en radicalen van ideogrammen. Sorteren is ook afhankelijk van de volgordetalen en culturen die voor het alfabet worden gebruikt. De Deense taal heeft bijvoorbeeld een 'Æ'-teken dat wordt gesorteerd na 'Z' in het alfabet. Bovendien kunnen vergelijkingen hoofdlettergevoelig of niet hoofdlettergevoelig zijn, en regels voor hoofdlettergebruik kunnen verschillen per cultuur. Ordinale vergelijking gebruikt daarentegen de Unicode-codepunten van afzonderlijke tekens in een tekenreeks bij het vergelijken en sorteren van tekenreeksen.
Sorteerregels bepalen de alfabetische volgorde van Unicode-tekens en hoe twee tekenreeksen met elkaar worden vergeleken. Bijvoorbeeld, de String.Compare(String, String, StringComparison) methode vergelijkt twee tekenreeksen op basis van de StringComparison parameter. Als de parameterwaarde is StringComparison.CurrentCulture, voert de methode een taalkundige vergelijking uit die gebruikmaakt van de conventies van de huidige cultuur; als de parameterwaarde is StringComparison.Ordinal, voert de methode een rangtelvergelijking uit. Als gevolg daarvan toont het volgende voorbeeld dat, als de huidige cultuur Amerikaans Engels is, de eerste aanroep naar de String.Compare(String, String, StringComparison)-methode (met behulp van cultuurgevoelige vergelijking) beschouwt "a" als kleiner dan "A", maar de tweede aanroep van dezelfde methode (met behulp van ordinale vergelijking) beschouwt "a" als groter dan "A".
using System;
using System.Globalization;
using System.Threading;
public class Example2
{
public static void Main()
{
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
Console.WriteLine(String.Compare("A", "a", StringComparison.CurrentCulture));
Console.WriteLine(String.Compare("A", "a", StringComparison.Ordinal));
}
}
// The example displays the following output:
// 1
// -32
open System
open System.Globalization
open System.Threading
Thread.CurrentThread.CurrentCulture <- CultureInfo.CreateSpecificCulture "en-US"
printfn $"""{String.Compare("A", "a", StringComparison.CurrentCulture)}"""
printfn $"""{String.Compare("A", "a", StringComparison.Ordinal)}"""
// The example displays the following output:
// 1
// -32
Imports System.Globalization
Imports System.Threading
Module Example3
Public Sub Main()
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US")
Console.WriteLine(String.Compare("A", "a", StringComparison.CurrentCulture))
Console.WriteLine(String.Compare("A", "a", StringComparison.Ordinal))
End Sub
End Module
' The example displays the following output:
' 1
' -32
.NET ondersteunt regels voor woorden, tekenreeksen en ordinale sorteervolgorde.
Een woordensortering voert een cultuurgevoelige vergelijking uit van tekenreeksen waarin bepaalde niet-alfanumerische Unicode-tekens mogelijk speciale gewichten toegewezen kunnen hebben. Aan het afbreekstreepje (-) kan bijvoorbeeld een zeer klein gewicht zijn toegewezen, zodat 'coop' en 'co-op' naast elkaar worden weergegeven in een gesorteerde lijst. Zie de String voor een lijst met methoden waarmee twee tekenreeksen worden vergeleken met behulp van sorteerregels voor woorden.
Tekenreeksortering verricht ook een cultuurgevoelige vergelijking. Het is vergelijkbaar met een woordsortering, behalve dat er geen speciale gevallen zijn en dat alle niet-alfanumerieke Unicode-tekens voorafgaan aan alle alfanumerieke Unicode-tekens. Twee tekenreeksen kunnen worden vergeleken met behulp van regels voor tekenreekssortering door de CompareInfo.Compare methode-overloads aan te roepen die een
optionsparameter met een waarde van CompareOptions.StringSort ontvangen. Houd er rekening mee dat dit de enige methode is die .NET biedt om twee tekenreeksen te vergelijken met behulp van tekenreekssorteerdregels.Met een ordinale sortering worden strings vergeleken op basis van de numerieke waarde van elk Char object in de string. Een rangtelvergelijking is automatisch hoofdlettergevoelig omdat de kleine letters en hoofdletters van een teken verschillende codepunten hebben. Als case echter niet belangrijk is, kunt u een rangtelvergelijking opgeven die hoofdlettergebruik negeert. Dit komt overeen met het converteren van de tekenreeks naar hoofdletters met behulp van de invariante cultuur en het uitvoeren van een rangtelkundige vergelijking op het resultaat. Zie de String voor een lijst met methoden waarmee twee tekenreeksen worden vergeleken met behulp van ordinale sorteerregels.
Een cultuurgevoelige vergelijking is een vergelijking die expliciet of impliciet gebruikmaakt van een CultureInfo object, met inbegrip van de invariante cultuur die door de CultureInfo.InvariantCulture eigenschap wordt opgegeven. De impliciete cultuur is de huidige cultuur, die wordt opgegeven door de Thread.CurrentCulture en CultureInfo.CurrentCulture eigenschappen. Er is aanzienlijke variatie in de sorteervolgorde van alfabetische tekens (dat wil gezegd, tekens waarvoor de Char.IsLetter eigenschap retourneert true) in culturen. U kunt een cultuurgevoelige vergelijking opgeven die gebruikmaakt van de conventies van een specifieke cultuur door een CultureInfo object op te geven aan een tekenreeksvergelijkingsmethode, zoals Compare(String, String, CultureInfo, CompareOptions). U kunt een cultuurgevoelige vergelijking opgeven die gebruikmaakt van de conventies van de huidige cultuur door StringComparison.CurrentCulture, StringComparison.CurrentCultureIgnoreCase, of elk ander lid van de CompareOptions opsomming, behalve CompareOptions.Ordinal of CompareOptions.OrdinalIgnoreCase, aan een geschikte overload van de Compare methode te verstrekken. Een cultuurgevoelige vergelijking is over het algemeen geschikt voor sorteren, terwijl een rangtelvergelijking dat niet is. Een ordinale vergelijking is over het algemeen geschikt om te bepalen of twee tekenreeksen gelijk zijn (dat wil zeggen, voor het bepalen van identiteit), terwijl een cultuurgevoelige vergelijking dat niet is.
In het volgende voorbeeld ziet u het verschil tussen cultuurgevoelige en rangtelkundige vergelijking. In het voorbeeld worden drie tekenreeksen geëvalueerd: 'Apple', 'Æble' en 'AEble', met behulp van ordinale vergelijking en de conventies van de da-DK- en en-US-cultuur (elk is de standaardcultuur op het moment dat de Compare methode wordt aangeroepen). Omdat de Deense taal het teken "Æ" als een afzonderlijke letter behandelt en deze sorteert na "Z" in het alfabet, is de tekenreeks "Æble" groter dan "Apple". "Æble" wordt echter niet beschouwd als gelijkwaardig aan "AEble", dus "Æble" is ook groter dan "AEble". De en-US-cultuur bevat niet de letter "Æ", maar behandelt deze als gelijkwaardig aan "AE", wat verklaart waarom "Æble" kleiner is dan "Apple" maar gelijk is aan "AEble". De ordinale vergelijking daarentegen beschouwt "Apple" als kleiner dan "Æble", en "Æble" als groter dan "AEble".
using System;
using System.Globalization;
using System.Threading;
public class CompareStringSample
{
public static void Main()
{
string str1 = "Apple";
string str2 = "Æble";
string str3 = "AEble";
// Set the current culture to Danish in Denmark.
Thread.CurrentThread.CurrentCulture = new CultureInfo("da-DK");
Console.WriteLine($"Current culture: {CultureInfo.CurrentCulture.Name}");
Console.WriteLine($"Comparison of {str1} with {str2}: {String.Compare(str1, str2)}");
Console.WriteLine($"Comparison of {str2} with {str3}: {String.Compare(str2, str3)}\n");
// Set the current culture to English in the U.S.
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
Console.WriteLine($"Current culture: {CultureInfo.CurrentCulture.Name}");
Console.WriteLine($"Comparison of {str1} with {str2}: {String.Compare(str1, str2)}");
Console.WriteLine($"Comparison of {str2} with {str3}: {String.Compare(str2, str3)}\n");
// Perform an ordinal comparison.
Console.WriteLine("Ordinal comparison");
Console.WriteLine($"Comparison of {str1} with {str2}: {String.Compare(str1, str2, StringComparison.Ordinal)}");
Console.WriteLine($"Comparison of {str2} with {str3}: {String.Compare(str2, str3, StringComparison.Ordinal)}");
}
}
// The example displays the following output:
// Current culture: da-DK
// Comparison of Apple with Æble: -1
// Comparison of Æble with AEble: 1
//
// Current culture: en-US
// Comparison of Apple with Æble: 1
// Comparison of Æble with AEble: 0
//
// Ordinal comparison
// Comparison of Apple with Æble: -133
// Comparison of Æble with AEble: 133
open System
open System.Globalization
open System.Threading
let str1 = "Apple"
let str2 = "Æble"
let str3 = "AEble"
// Set the current culture to Danish in Denmark.
Thread.CurrentThread.CurrentCulture <- CultureInfo "da-DK"
printfn $"Current culture: {CultureInfo.CurrentCulture.Name}"
printfn $"Comparison of {str1} with {str2}: {String.Compare(str1, str2)}"
printfn $"Comparison of {str2} with {str3}: {String.Compare(str2, str3)}\n"
// Set the current culture to English in the U.S.
Thread.CurrentThread.CurrentCulture <- CultureInfo "en-US"
printfn $"Current culture: {CultureInfo.CurrentCulture.Name}"
printfn $"Comparison of {str1} with {str2}: {String.Compare(str1, str2)}"
printfn $"Comparison of {str2} with {str3}: {String.Compare(str2, str3)}\n"
// Perform an ordinal comparison.
printfn "Ordinal comparison"
printfn $"Comparison of {str1} with {str2}: {String.Compare(str1, str2, StringComparison.Ordinal)}"
printfn $"Comparison of {str2} with {str3}: {String.Compare(str2, str3, StringComparison.Ordinal)}"
// The example displays the following output:
// Current culture: da-DK
// Comparison of Apple with Æble: -1
// Comparison of Æble with AEble: 1
//
// Current culture: en-US
// Comparison of Apple with Æble: 1
// Comparison of Æble with AEble: 0
//
// Ordinal comparison
// Comparison of Apple with Æble: -133
// Comparison of Æble with AEble: 133
Imports System.Globalization
Imports System.Threading
Public Module Example6
Public Sub Main()
Dim str1 As String = "Apple"
Dim str2 As String = "Æble"
Dim str3 As String = "AEble"
' Set the current culture to Danish in Denmark.
Thread.CurrentThread.CurrentCulture = New CultureInfo("da-DK")
Console.WriteLine("Current culture: {0}",
CultureInfo.CurrentCulture.Name)
Console.WriteLine("Comparison of {0} with {1}: {2}",
str1, str2, String.Compare(str1, str2))
Console.WriteLine("Comparison of {0} with {1}: {2}",
str2, str3, String.Compare(str2, str3))
Console.WriteLine()
' Set the current culture to English in the U.S.
Thread.CurrentThread.CurrentCulture = New CultureInfo("en-US")
Console.WriteLine("Current culture: {0}",
CultureInfo.CurrentCulture.Name)
Console.WriteLine("Comparison of {0} with {1}: {2}",
str1, str2, String.Compare(str1, str2))
Console.WriteLine("Comparison of {0} with {1}: {2}",
str2, str3, String.Compare(str2, str3))
Console.WriteLine()
' Perform an ordinal comparison.
Console.WriteLine("Ordinal comparison")
Console.WriteLine("Comparison of {0} with {1}: {2}",
str1, str2,
String.Compare(str1, str2, StringComparison.Ordinal))
Console.WriteLine("Comparison of {0} with {1}: {2}",
str2, str3,
String.Compare(str2, str3, StringComparison.Ordinal))
End Sub
End Module
' The example displays the following output:
' Current culture: da-DK
' Comparison of Apple with Æble: -1
' Comparison of Æble with AEble: 1
'
' Current culture: en-US
' Comparison of Apple with Æble: 1
' Comparison of Æble with AEble: 0
'
' Ordinal comparison
' Comparison of Apple with Æble: -133
' Comparison of Æble with AEble: 133
Gebruik de volgende algemene richtlijnen om een geschikte sorteer- of tekenreeksvergelijkingsmethode te kiezen:
Als u wilt dat de tekenreeksen worden geordend volgens de cultuur van de gebruiker, dient u ze te ordenen volgens de conventies van de huidige cultuur. Als de cultuur van de gebruiker verandert, wordt de volgorde van gesorteerde tekenreeksen ook dienovereenkomstig gewijzigd. Een synoniemenlijsttoepassing moet bijvoorbeeld altijd woorden sorteren op basis van de cultuur van de gebruiker.
Als u wilt dat de tekenreeksen worden geordend op basis van de conventies van een specifieke cultuur, moet u deze rangschikken door een CultureInfo object op te geven dat die cultuur aan een vergelijkingsmethode vertegenwoordigt. In een toepassing die is ontworpen om studenten een bepaalde taal te leren, wilt u bijvoorbeeld dat tekenreeksen worden gerangschikt op basis van de conventies van een cultuur die die taal spreekt.
Als u wilt dat de volgorde van tekenreeksen ongewijzigd blijft in verschillende culturen, moet u ze ordenen op basis van de conventies van de invariante cultuur of een rangtelvergelijking gebruiken. U kunt bijvoorbeeld een ordinale sortering gebruiken om de namen van bestanden, processen, mutexes of benoemde pijpen te ordenen.
Voor een vergelijking waarbij een beveiligingsbeslissing is vereist (zoals of een gebruikersnaam geldig is), moet u altijd een ordinale test uitvoeren op gelijkheid door een overbelasting van de Equals methode aan te roepen.
Notitie
De cultuurgevoelige sorteer- en casingregels die in tekenreeksvergelijking worden gebruikt, zijn afhankelijk van de versie van .NET. Voor .NET Core is de vergelijking van tekenreeksen afhankelijk van de versie van de Unicode Standard die wordt ondersteund door het onderliggende besturingssysteem. In .NET Framework 4.5 en latere versies die worden uitgevoerd op Windows 8 of hoger, voldoen sortering, behuizing, normalisatie en Unicode-tekeninformatie aan de Unicode 6.0-standaard. Op andere Windows-besturingssystemen voldoen ze aan de Unicode 5.0-standaard.
Zie het System.Globalization.CompareOptions onderwerp voor meer informatie over regels voor woord, tekenreeks en ordinale sortering. Zie Aanbevolen procedures voor het gebruik van tekenreeksen voor aanvullende aanbevelingen voor het gebruik van elke regel.
Normaal gesproken roept u geen vergelijkingsmethoden voor tekenreeksen aan, zoals Compare rechtstreeks om de sorteervolgorde van tekenreeksen te bepalen. In plaats daarvan worden vergelijkingsmethoden aangeroepen door sorteermethoden zoals Array.Sort of List<T>.Sort. In het volgende voorbeeld worden vier verschillende sorteerbewerkingen uitgevoerd (woorden sorteren met de huidige cultuur, woordsortering met behulp van de invariante cultuur, rangschikken en sorteren van tekenreeksen met behulp van de invariante cultuur) zonder expliciet een tekenreeksvergelijkingsmethode aan te roepen, hoewel ze wel het type vergelijking opgeven dat moet worden gebruikt. Elk type sortering produceert een unieke volgorde van tekenreeksen in de matrix.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
public class Example3
{
public static void Main()
{
string[] strings = { "coop", "co-op", "cooperative",
"co\u00ADoperative", "cœur", "coeur" };
// Perform a word sort using the current (en-US) culture.
string[] current = new string[strings.Length];
strings.CopyTo(current, 0);
Array.Sort(current, StringComparer.CurrentCulture);
// Perform a word sort using the invariant culture.
string[] invariant = new string[strings.Length];
strings.CopyTo(invariant, 0);
Array.Sort(invariant, StringComparer.InvariantCulture);
// Perform an ordinal sort.
string[] ordinal = new string[strings.Length];
strings.CopyTo(ordinal, 0);
Array.Sort(ordinal, StringComparer.Ordinal);
// Perform a string sort using the current culture.
string[] stringSort = new string[strings.Length];
strings.CopyTo(stringSort, 0);
Array.Sort(stringSort, new SCompare());
// Display array values
Console.WriteLine("{0,13} {1,13} {2,15} {3,13} {4,13}\n",
"Original", "Word Sort", "Invariant Word",
"Ordinal Sort", "String Sort");
for (int ctr = 0; ctr < strings.Length; ctr++)
Console.WriteLine("{0,13} {1,13} {2,15} {3,13} {4,13}",
strings[ctr], current[ctr], invariant[ctr],
ordinal[ctr], stringSort[ctr] );
}
}
// IComparer<String> implementation to perform string sort.
internal class SCompare : IComparer<String>
{
public int Compare(string x, string y)
{
return CultureInfo.CurrentCulture.CompareInfo.Compare(x, y, CompareOptions.StringSort);
}
}
// The example displays the following output:
// Original Word Sort Invariant Word Ordinal Sort String Sort
//
// coop cœur cœur co-op co-op
// co-op coeur coeur coeur cœur
// cooperative coop coop coop coeur
// cooperative co-op co-op cooperative coop
// cœur cooperative cooperative cooperative cooperative
// coeur cooperative cooperative cœur cooperative
open System
open System.Collections.Generic
open System.Globalization
// IComparer<String> implementation to perform string sort using an F# object expression.
let scompare =
{ new IComparer<String> with
member _.Compare(x, y) =
CultureInfo.CurrentCulture.CompareInfo.Compare(x, y, CompareOptions.StringSort) }
let strings = [| "coop"; "co-op"; "cooperative"; "co\u00ADoperative"; "cœur"; "coeur" |]
// Perform a word sort using the current (en-US) culture.
let current = Array.copy strings
Array.Sort(current, StringComparer.CurrentCulture)
// Perform a word sort using the invariant culture.
let invariant = Array.copy strings
Array.Sort(invariant, StringComparer.InvariantCulture)
// Perform an ordinal sort.
let ordinal = Array.copy strings
Array.Sort(ordinal, StringComparer.Ordinal)
// Perform a string sort using the current culture.
let stringSort = Array.copy strings
Array.Sort(stringSort, scompare)
// Display array values
printfn "%13s %13s %15s %13s %13s\n" "Original" "Word Sort" "Invariant Word" "Ordinal Sort" "String Sort"
for i = 0 to strings.Length - 1 do
printfn "%13s %13s %15s %13s %13s\n" strings[i] current[i] invariant[i] ordinal[i] stringSort[i]
// The example displays the following output:
// Original Word Sort Invariant Word Ordinal Sort String Sort
//
// coop cœur cœur co-op co-op
// co-op coeur coeur coeur cœur
// cooperative coop coop coop coeur
// cooperative co-op co-op cooperative coop
// cœur cooperative cooperative cooperative cooperative
// coeur cooperative cooperative cœur cooperative
Imports System.Collections
Imports System.Collections.Generic
Imports System.Globalization
Module Example4
Public Sub Main()
Dim strings() As String = {"coop", "co-op", "cooperative",
"co" + ChrW(&HAD) + "operative",
"cœur", "coeur"}
' Perform a word sort using the current (en-US) culture.
Dim current(strings.Length - 1) As String
strings.CopyTo(current, 0)
Array.Sort(current, StringComparer.CurrentCulture)
' Perform a word sort using the invariant culture.
Dim invariant(strings.Length - 1) As String
strings.CopyTo(invariant, 0)
Array.Sort(invariant, StringComparer.InvariantCulture)
' Perform an ordinal sort.
Dim ordinal(strings.Length - 1) As String
strings.CopyTo(ordinal, 0)
Array.Sort(ordinal, StringComparer.Ordinal)
' Perform a string sort using the current culture.
Dim stringSort(strings.Length - 1) As String
strings.CopyTo(stringSort, 0)
Array.Sort(stringSort, New SCompare())
' Display array values
Console.WriteLine("{0,13} {1,13} {2,15} {3,13} {4,13}",
"Original", "Word Sort", "Invariant Word",
"Ordinal Sort", "String Sort")
Console.WriteLine()
For ctr As Integer = 0 To strings.Length - 1
Console.WriteLine("{0,13} {1,13} {2,15} {3,13} {4,13}",
strings(ctr), current(ctr), invariant(ctr),
ordinal(ctr), stringSort(ctr))
Next
End Sub
End Module
' IComparer<String> implementation to perform string sort.
Friend Class SCompare : Implements IComparer(Of String)
Public Function Compare(x As String, y As String) As Integer _
Implements IComparer(Of String).Compare
Return CultureInfo.CurrentCulture.CompareInfo.Compare(x, y, CompareOptions.StringSort)
End Function
End Class
' The example displays the following output:
' Original Word Sort Invariant Word Ordinal Sort String Sort
'
' coop cœur cœur co-op co-op
' co-op coeur coeur coeur cœur
' cooperative coop coop coop coeur
' cooperative co-op co-op cooperative coop
' cœur cooperative cooperative cooperative cooperative
' coeur cooperative cooperative cœur cooperative
Aanbeveling
Intern gebruikt .NET sorteersleutels ter ondersteuning van cultureel gevoelige tekenreeksvergelijking. Elk teken in een tekenreeks krijgt verschillende categorieën sorteergewichten, waaronder alfabetisch, hoofdletters en diakritische tekens. Een sorteersleutel, vertegenwoordigd door de SortKey klasse, biedt een opslagplaats van deze gewichten voor een bepaalde tekenreeks. Als uw app een groot aantal zoek- of sorteerbewerkingen uitvoert op dezelfde reeks tekenreeksen, kunt u de prestaties verbeteren door sorteersleutels te genereren en op te slaan voor alle tekenreeksen die worden gebruikt. Wanneer een sorteer- of vergelijkingsbewerking is vereist, gebruikt u de sorteersleutels in plaats van de tekenreeksen. Zie de SortKey klas voor meer informatie.
Als u geen tekenreeksvergelijkingsconventie opgeeft, voeren methoden zoals Array.Sort(Array) een cultuurgevoelige, hoofdlettergevoelige sortering uit op tekenreeksen. In het volgende voorbeeld ziet u hoe het wijzigen van de huidige cultuur van invloed is op de volgorde van gesorteerde tekenreeksen in een matrix. Er wordt een array van drie strings gemaakt. Eerst wordt de System.Threading.Thread.CurrentThread.CurrentCulture eigenschap ingesteld op en-US en wordt de methode aangeroepen Array.Sort(Array) . De resulterende sorteervolgorde is gebaseerd op sorteerconventies voor de Engelse cultuur (Verenigde Staten). Vervolgens wordt in het voorbeeld de System.Threading.Thread.CurrentThread.CurrentCulture eigenschap ingesteld op da-DK en wordt de Array.Sort methode opnieuw aangeroepen. U ziet hoe de resulterende sorteervolgorde verschilt van de en-US-resultaten omdat de sorteerconventies voor Deens (Denemarken) worden gebruikt.
using System;
using System.Globalization;
using System.Threading;
public class ArraySort
{
public static void Main(String[] args)
{
// Create and initialize a new array to store the strings.
string[] stringArray = { "Apple", "Æble", "Zebra"};
// Display the values of the array.
Console.WriteLine( "The original string array:");
PrintIndexAndValues(stringArray);
// Set the CurrentCulture to "en-US".
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
// Sort the values of the array.
Array.Sort(stringArray);
// Display the values of the array.
Console.WriteLine("After sorting for the culture \"en-US\":");
PrintIndexAndValues(stringArray);
// Set the CurrentCulture to "da-DK".
Thread.CurrentThread.CurrentCulture = new CultureInfo("da-DK");
// Sort the values of the Array.
Array.Sort(stringArray);
// Display the values of the array.
Console.WriteLine("After sorting for the culture \"da-DK\":");
PrintIndexAndValues(stringArray);
}
public static void PrintIndexAndValues(string[] myArray)
{
for (int i = myArray.GetLowerBound(0); i <=
myArray.GetUpperBound(0); i++ )
Console.WriteLine($"[{i}]: {myArray[i]}");
Console.WriteLine();
}
}
// The example displays the following output:
// The original string array:
// [0]: Apple
// [1]: Æble
// [2]: Zebra
//
// After sorting for the "en-US" culture:
// [0]: Æble
// [1]: Apple
// [2]: Zebra
//
// After sorting for the culture "da-DK":
// [0]: Apple
// [1]: Zebra
// [2]: Æble
open System
open System.Globalization
open System.Threading
let printIndexAndValues (myArray: string[]) =
for i = myArray.GetLowerBound 0 to myArray.GetUpperBound 0 do
printfn $"[{i}]: {myArray[i]}"
printfn ""
// Create and initialize a new array to store the strings.
let stringArray = [| "Apple"; "Æble"; "Zebra" |]
// Display the values of the array.
printfn "The original string array:"
printIndexAndValues stringArray
// Set the CurrentCulture to "en-US".
Thread.CurrentThread.CurrentCulture <- CultureInfo "en-US"
// Sort the values of the array.
Array.Sort stringArray
// Display the values of the array.
printfn "After sorting for the culture \"en-US\":"
printIndexAndValues stringArray
// Set the CurrentCulture to "da-DK".
Thread.CurrentThread.CurrentCulture <- CultureInfo "da-DK"
// Sort the values of the Array.
Array.Sort stringArray
// Display the values of the array.
printfn "After sorting for the culture \"da-DK\":"
printIndexAndValues stringArray
// The example displays the following output:
// The original string array:
// [0]: Apple
// [1]: Æble
// [2]: Zebra
//
// After sorting for the "en-US" culture:
// [0]: Æble
// [1]: Apple
// [2]: Zebra
//
// After sorting for the culture "da-DK":
// [0]: Apple
// [1]: Zebra
// [2]: Æble
Imports System.Globalization
Imports System.IO
Imports System.Threading
Public Class TextToFile
Public Shared Sub Main()
' Creates and initializes a new array to store
' these date/time objects.
Dim stringArray() As String = { "Apple", "Æble", "Zebra"}
' Displays the values of the array.
Console.WriteLine("The original string array:")
PrintIndexAndValues(stringArray)
' Set the CurrentCulture to "en-US".
Thread.CurrentThread.CurrentCulture = New CultureInfo("en-US")
' Sort the values of the Array.
Array.Sort(stringArray)
' Display the values of the array.
Console.WriteLine("After sorting for the ""en-US"" culture:")
PrintIndexAndValues(stringArray)
' Set the CurrentCulture to "da-DK".
Thread.CurrentThread.CurrentCulture = New CultureInfo("da-DK")
' Sort the values of the Array.
Array.Sort(stringArray)
' Displays the values of the Array.
Console.WriteLine("After sorting for the culture ""da-DK"":")
PrintIndexAndValues(stringArray)
End Sub
Public Shared Sub PrintIndexAndValues(myArray() As String)
For i As Integer = myArray.GetLowerBound(0) To myArray.GetUpperBound(0)
Console.WriteLine("[{0}]: {1}", i, myArray(i))
Next
Console.WriteLine()
End Sub
End Class
' The example displays the following output:
' The original string array:
' [0]: Apple
' [1]: Æble
' [2]: Zebra
'
' After sorting for the "en-US" culture:
' [0]: Æble
' [1]: Apple
' [2]: Zebra
'
' After sorting for the culture "da-DK":
' [0]: Apple
' [1]: Zebra
' [2]: Æble
Waarschuwing
Als uw primaire doel bij het vergelijken van tekenreeksen is om te bepalen of ze gelijk zijn, moet u de String.Equals methode aanroepen. Meestal moet u Equals gebruiken om een ordinale vergelijking uit te voeren. De String.Compare methode is voornamelijk bedoeld om tekenreeksen te sorteren.
Zoekmethoden voor tekenreeksen, zoals String.StartsWith en String.IndexOf, kunnen ook cultuurgevoelige ordinale tekenreeksvergelijkingen uitvoeren. In het volgende voorbeeld ziet u de verschillen tussen ordinale en cultuurgevoelige vergelijkingen met behulp van de IndexOf methode. Een cultuurgevoelige zoekopdracht, waarbij de huidige cultuur Engels (Verenigde Staten) is, beschouwt de subtekenreeks 'oe' als overeenkomend met de ligatuur "œ". Omdat een zacht afbreekstreepje (U+00AD) een teken met nul breedte is, behandelt de zoekopdracht het zachte afbreekstreepje als gelijkwaardig aan String.Empty en vindt een overeenkomst aan het begin van de tekenreeks. Een ordinale zoekopdracht vindt daarentegen geen overeenkomst in beide gevallen.
using System;
public class Example8
{
public static void Main()
{
// Search for "oe" and "œu" in "œufs" and "oeufs".
string s1 = "œufs";
string s2 = "oeufs";
FindInString(s1, "oe", StringComparison.CurrentCulture);
FindInString(s1, "oe", StringComparison.Ordinal);
FindInString(s2, "œu", StringComparison.CurrentCulture);
FindInString(s2, "œu", StringComparison.Ordinal);
Console.WriteLine();
string s3 = "co\u00ADoperative";
FindInString(s3, "\u00AD", StringComparison.CurrentCulture);
FindInString(s3, "\u00AD", StringComparison.Ordinal);
}
private static void FindInString(string s, string substring, StringComparison options)
{
int result = s.IndexOf(substring, options);
if (result != -1)
Console.WriteLine($"'{substring}' found in {s} at position {result}");
else
Console.WriteLine($"'{substring}' not found in {s}");
}
}
// The example displays the following output:
// 'oe' found in œufs at position 0
// 'oe' not found in œufs
// 'œu' found in oeufs at position 0
// 'œu' not found in oeufs
//
// '' found in cooperative at position 0
// '' found in cooperative at position 2
open System
let findInString (s: string) (substring: string) (options: StringComparison) =
let result = s.IndexOf(substring, options)
if result <> -1 then
printfn $"'{substring}' found in {s} at position {result}"
else
printfn $"'{substring}' not found in {s}"
// Search for "oe" and "œu" in "œufs" and "oeufs".
let s1 = "œufs"
let s2 = "oeufs"
findInString s1 "oe" StringComparison.CurrentCulture
findInString s1 "oe" StringComparison.Ordinal
findInString s2 "œu" StringComparison.CurrentCulture
findInString s2 "œu" StringComparison.Ordinal
printfn ""
let s3 = "co\u00ADoperative"
findInString s3 "\u00AD" StringComparison.CurrentCulture
findInString s3 "\u00AD" StringComparison.Ordinal
// The example displays the following output:
// 'oe' found in œufs at position 0
// 'oe' not found in œufs
// 'œu' found in oeufs at position 0
// 'œu' not found in oeufs
//
// '' found in cooperative at position 0
// '' found in cooperative at position 2
Module Example5
Public Sub Main()
' Search for "oe" and "œu" in "œufs" and "oeufs".
Dim s1 As String = "œufs"
Dim s2 As String = "oeufs"
FindInString(s1, "oe", StringComparison.CurrentCulture)
FindInString(s1, "oe", StringComparison.Ordinal)
FindInString(s2, "œu", StringComparison.CurrentCulture)
FindInString(s2, "œu", StringComparison.Ordinal)
Console.WriteLine()
Dim softHyphen As String = ChrW(&HAD)
Dim s3 As String = "co" + softHyphen + "operative"
FindInString(s3, softHyphen, StringComparison.CurrentCulture)
FindInString(s3, softHyphen, StringComparison.Ordinal)
End Sub
Private Sub FindInString(s As String, substring As String,
options As StringComparison)
Dim result As Integer = s.IndexOf(substring, options)
If result <> -1 Then
Console.WriteLine("'{0}' found in {1} at position {2}",
substring, s, result)
Else
Console.WriteLine("'{0}' not found in {1}",
substring, s)
End If
End Sub
End Module
' The example displays the following output:
' 'oe' found in œufs at position 0
' 'oe' not found in œufs
' 'œu' found in oeufs at position 0
' 'œu' not found in oeufs
'
' '' found in cooperative at position 0
' '' found in cooperative at position 2
Zoeken in tekenreeksen
Zoekmethoden voor tekenreeksen, zoals String.StartsWith en String.IndexOf, kunnen ook cultuurgevoelige ordinale tekenreeksvergelijkingen uitvoeren om te bepalen of een teken of subtekenreeks wordt gevonden in een opgegeven tekenreeks.
De zoekmethoden in de String klasse die zoeken naar een afzonderlijk teken, zoals de IndexOf methode, of een van een reeks tekens, zoals de IndexOfAny methode, voeren allemaal een rangschikkerzoekopdracht uit. Als u een cultuurgevoelige zoekopdracht voor een karakter wilt uitvoeren, moet u een methode aanroepen, zoals CompareInfo, CompareInfo.IndexOf(String, Char) of CompareInfo.LastIndexOf(String, Char). Houd er rekening mee dat de resultaten van het zoeken naar een teken met behulp van ordinale en cultuurgevoelige vergelijking heel anders kunnen zijn. Een zoekopdracht naar een vooraf samengesteld Unicode-teken, zoals de ligatuur 'Æ' (U+00C6), kan bijvoorbeeld overeenkomen met elke voorkomens van de onderdelen in de juiste volgorde, zoals 'AE' (U+0041U+0045), afhankelijk van de cultuur. In het volgende voorbeeld ziet u het verschil tussen de String.IndexOf(Char) en CompareInfo.IndexOf(String, Char) methoden bij het zoeken naar een afzonderlijk teken. De ligatuur "æ" (U+00E6) komt voor in de reeks "aerial" bij gebruik van de conventies van de en-US-cultuur, maar niet bij gebruik van de conventies van de da-DK-cultuur of bij een ordinale vergelijking.
using System;
using System.Globalization;
public class Example17
{
public static void Main()
{
String[] cultureNames = { "da-DK", "en-US" };
CompareInfo ci;
String str = "aerial";
Char ch = 'æ'; // U+00E6
Console.Write("Ordinal comparison -- ");
Console.WriteLine($"Position of '{ch}' in {str}: {str.IndexOf(ch)}");
foreach (var cultureName in cultureNames) {
ci = CultureInfo.CreateSpecificCulture(cultureName).CompareInfo;
Console.Write("{0} cultural comparison -- ", cultureName);
Console.WriteLine($"Position of '{ch}' in {str}: {ci.IndexOf(str, ch)}");
}
}
}
// The example displays the following output:
// Ordinal comparison -- Position of 'æ' in aerial: -1
// da-DK cultural comparison -- Position of 'æ' in aerial: -1
// en-US cultural comparison -- Position of 'æ' in aerial: 0
open System.Globalization
let cultureNames = [| "da-DK"; "en-US" |]
let str = "aerial"
let ch = 'æ' // U+00E6
printf "Ordinal comparison -- "
printfn $"Position of '{ch}' in {str}: {str.IndexOf ch}"
for cultureName in cultureNames do
let ci = CultureInfo.CreateSpecificCulture(cultureName).CompareInfo
printf $"{cultureName} cultural comparison -- "
printfn $"Position of '{ch}' in {str}: {ci.IndexOf(str, ch)}"
// The example displays the following output:
// Ordinal comparison -- Position of 'æ' in aerial: -1
// da-DK cultural comparison -- Position of 'æ' in aerial: -1
// en-US cultural comparison -- Position of 'æ' in aerial: 0
Imports System.Globalization
Module Example19
Public Sub Main()
Dim cultureNames() As String = {"da-DK", "en-US"}
Dim ci As CompareInfo
Dim str As String = "aerial"
Dim ch As Char = "æ"c ' U+00E6
Console.Write("Ordinal comparison -- ")
Console.WriteLine("Position of '{0}' in {1}: {2}", ch, str,
str.IndexOf(ch))
For Each cultureName In cultureNames
ci = CultureInfo.CreateSpecificCulture(cultureName).CompareInfo
Console.Write("{0} cultural comparison -- ", cultureName)
Console.WriteLine("Position of '{0}' in {1}: {2}", ch, str,
ci.IndexOf(str, ch))
Next
End Sub
End Module
' The example displays the following output:
' Ordinal comparison -- Position of 'æ' in aerial: -1
' da-DK cultural comparison -- Position of 'æ' in aerial: -1
' en-US cultural comparison -- Position of 'æ' in aerial: 0
Aan de andere kant String voeren klassemethoden die zoeken naar een tekenreeks in plaats van een teken een cultuurgevoelige zoekopdracht uit als zoekopties niet expliciet worden opgegeven door een parameter van het type StringComparison. De enige uitzondering hierop is Contains, waarmee een rangschikkelijk onderzoek wordt uitgevoerd.
Testen op gelijkheid
Gebruik de String.Compare methode om de relatie van twee tekenreeksen in de sorteervolgorde te bepalen. Dit is doorgaans een cultuurgevoelige bewerking. Roep daarentegen de String.Equals methode aan om te testen op gelijkheid. Omdat de test op gelijkheid meestal gebruikersinvoer vergelijkt met een bekende tekenreeks, zoals een geldige gebruikersnaam, een wachtwoord of een bestandssysteempad, is dit meestal een ordinale bewerking.
Waarschuwing
Het is mogelijk om te testen op gelijkheid door de String.Compare methode aan te roepen en te bepalen of de retourwaarde nul is. Deze praktijk wordt echter niet aanbevolen. Als u wilt bepalen of twee tekenreeksen gelijk zijn, moet u een van de overbelastingen van de String.Equals methode aanroepen. De voorkeursoverbelasting die moet worden aangeroepen, is de instantiemethode Equals(String, StringComparison) of de statische Equals(String, String, StringComparison) methode, omdat beide methoden een System.StringComparison parameter bevatten die expliciet het type vergelijking aangeeft.
In het volgende voorbeeld wordt het gevaar geïllustreerd van het uitvoeren van een cultuurgevoelige vergelijking van gelijkheid wanneer in plaats daarvan een ordinale vergelijking moet worden toegepast. In dit geval is het de bedoeling van de code om toegang tot het bestandssysteem te verbieden van URL's die beginnen met 'FILE://' of 'file://' door een hoofdlettergevoelige vergelijking van het begin van een URL uit te voeren met de tekenreeks 'FILE://'. Als echter een cultuurgevoelige vergelijking wordt uitgevoerd met behulp van de Turkse cultuur (Turkije) op een URL die begint met 'file://', mislukt de vergelijking voor gelijkheid, omdat het Turkse hoofdlettere equivalent van de kleine letter 'i' 'İ' is in plaats van 'I'. Hierdoor is toegang tot het bestandssysteem per ongeluk toegestaan. Als daarentegen een rangtelvergelijking wordt uitgevoerd, slaagt de vergelijking voor gelijkheid en wordt de toegang tot het bestandssysteem geweigerd.
using System;
using System.Globalization;
using System.Threading;
public class Example4
{
public static void Main()
{
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("tr-TR");
string filePath = "file://c:/notes.txt";
Console.WriteLine("Culture-sensitive test for equality:");
if (! TestForEquality(filePath, StringComparison.CurrentCultureIgnoreCase))
Console.WriteLine($"Access to {filePath} is allowed.");
else
Console.WriteLine($"Access to {filePath} is not allowed.");
Console.WriteLine("\nOrdinal test for equality:");
if (! TestForEquality(filePath, StringComparison.OrdinalIgnoreCase))
Console.WriteLine($"Access to {filePath} is allowed.");
else
Console.WriteLine($"Access to {filePath} is not allowed.");
}
private static bool TestForEquality(string str, StringComparison cmp)
{
int position = str.IndexOf("://");
if (position < 0) return false;
string substring = str.Substring(0, position);
return substring.Equals("FILE", cmp);
}
}
// The example displays the following output:
// Culture-sensitive test for equality:
// Access to file://c:/notes.txt is allowed.
//
// Ordinal test for equality:
// Access to file://c:/notes.txt is not allowed.
open System
open System.Globalization
open System.Threading
let testForEquality (str: string) (cmp: StringComparison) =
let position = str.IndexOf "://"
if position < 0 then false
else
let substring = str.Substring(0, position)
substring.Equals("FILE", cmp)
Thread.CurrentThread.CurrentCulture <- CultureInfo.CreateSpecificCulture "tr-TR"
let filePath = "file://c:/notes.txt"
printfn "Culture-sensitive test for equality:"
if not (testForEquality filePath StringComparison.CurrentCultureIgnoreCase) then
printfn $"Access to {filePath} is allowed."
else
printfn $"Access to {filePath} is not allowed."
printfn "\nOrdinal test for equality:"
if not (testForEquality filePath StringComparison.OrdinalIgnoreCase) then
printfn $"Access to {filePath} is allowed."
else
printfn $"Access to {filePath} is not allowed."
// The example displays the following output:
// Culture-sensitive test for equality:
// Access to file://c:/notes.txt is allowed.
//
// Ordinal test for equality:
// Access to file://c:/notes.txt is not allowed.
Imports System.Globalization
Imports System.Threading
Module Example7
Public Sub Main()
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("tr-TR")
Dim filePath As String = "file://c:/notes.txt"
Console.WriteLine("Culture-sensitive test for equality:")
If Not TestForEquality(filePath, StringComparison.CurrentCultureIgnoreCase) Then
Console.WriteLine("Access to {0} is allowed.", filePath)
Else
Console.WriteLine("Access to {0} is not allowed.", filePath)
End If
Console.WriteLine()
Console.WriteLine("Ordinal test for equality:")
If Not TestForEquality(filePath, StringComparison.OrdinalIgnoreCase) Then
Console.WriteLine("Access to {0} is allowed.", filePath)
Else
Console.WriteLine("Access to {0} is not allowed.", filePath)
End If
End Sub
Private Function TestForEquality(str As String, cmp As StringComparison) As Boolean
Dim position As Integer = str.IndexOf("://")
If position < 0 Then Return False
Dim substring As String = str.Substring(0, position)
Return substring.Equals("FILE", cmp)
End Function
End Module
' The example displays the following output:
' Culture-sensitive test for equality:
' Access to file://c:/notes.txt is allowed.
'
' Ordinal test for equality:
' Access to file://c:/notes.txt is not allowed.
Normalisatie
Sommige Unicode-tekens hebben meerdere weergaven. Een van de volgende codepunten kan bijvoorbeeld de letter 'ắ' vertegenwoordigen:
- U+1EAF
- U+0103 U+0301
- U+0061 U+0306 U+0301
Meerdere weergaven voor één teken maken het zoeken, sorteren, vergelijken en andere tekenreeksbewerkingen ingewikkeld.
De Unicode-standaard definieert een proces met de naam normalisatie dat één binaire weergave van een Unicode-teken retourneert voor een van de equivalente binaire weergaven. Normalisatie kan verschillende algoritmen, normalisatieformulieren genoemd, gebruiken die verschillende regels volgen. .NET ondersteunt Unicode-normalisatievormen C, D, KC en KD. Wanneer tekenreeksen zijn genormaliseerd naar dezelfde normalisatievorm, kunnen ze worden vergeleken met behulp van rangtelkundige vergelijking.
Een ordinale vergelijking is een binaire vergelijking van de Unicode-schaalwaarde van overeenkomstige Char objecten in elke tekenreeks. De String klasse bevat een aantal methoden die een rangtelvergelijking kunnen uitvoeren, waaronder de volgende:
Elke overbelasting van de Compare, , , Equals, , StartsWithen EndsWithIndexOfmethoden die een LastIndexOfStringComparisonparameter bevatten. De methode voert een rangtelvergelijking uit als u een waarde van StringComparison.Ordinal of OrdinalIgnoreCase voor deze parameter opgeeft.
De overbelasting van de CompareOrdinal methode.
Methoden die standaard ordinale vergelijking gebruiken, zoals Contains, Replace en Split.
Methoden die zoeken naar een Char waarde of naar de elementen in een Char array in een tekenreeksinstantie. Dergelijke methoden omvatten IndexOf(Char) en Split(Char[]).
U kunt bepalen of een tekenreeks is genormaliseerd naar normalisatieformulier C door de String.IsNormalized() methode aan te roepen of u kunt de String.IsNormalized(NormalizationForm) methode aanroepen om te bepalen of een tekenreeks is genormaliseerd naar een opgegeven normalisatieformulier. U kunt de String.Normalize() methode ook aanroepen om een tekenreeks te converteren naar normalisatieformulier C of u kunt de String.Normalize(NormalizationForm) methode aanroepen om een tekenreeks te converteren naar een opgegeven normalisatieformulier. Zie de Normalize() en Normalize(NormalizationForm) methoden voor stapsgewijze informatie over het normaliseren en vergelijken van tekenreeksen.
In het volgende eenvoudige voorbeeld ziet u tekenreeksnormalisatie. Het definieert de letter 'ố' op drie verschillende manieren in drie verschillende tekenreeksen en gebruikt een rangtelvergelijking voor gelijkheid om te bepalen of elke tekenreeks verschilt van de andere twee tekenreeksen. Vervolgens wordt elke tekenreeks geconverteerd naar de ondersteunde normalisatieformulieren en wordt opnieuw een rangtelvergelijking van elke tekenreeks uitgevoerd in een opgegeven normalisatievorm. In elk geval toont de tweede test voor gelijkheid aan dat de tekenreeksen gelijk zijn.
using System;
using System.Globalization;
using System.IO;
using System.Text;
public class Example13
{
private static StreamWriter sw;
public static void Main()
{
sw = new StreamWriter(@".\TestNorm1.txt");
// Define three versions of the same word.
string s1 = "sống"; // create word with U+1ED1
string s2 = "s\u00F4\u0301ng";
string s3 = "so\u0302\u0301ng";
TestForEquality(s1, s2, s3);
sw.WriteLine();
// Normalize and compare strings using each normalization form.
foreach (string formName in Enum.GetNames(typeof(NormalizationForm)))
{
sw.WriteLine("Normalization {0}:\n", formName);
NormalizationForm nf = (NormalizationForm) Enum.Parse(typeof(NormalizationForm), formName);
string[] sn = NormalizeStrings(nf, s1, s2, s3);
TestForEquality(sn);
sw.WriteLine("\n");
}
sw.Close();
}
private static void TestForEquality(params string[] words)
{
for (int ctr = 0; ctr <= words.Length - 2; ctr++)
for (int ctr2 = ctr + 1; ctr2 <= words.Length - 1; ctr2++)
sw.WriteLine("{0} ({1}) = {2} ({3}): {4}",
words[ctr], ShowBytes(words[ctr]),
words[ctr2], ShowBytes(words[ctr2]),
words[ctr].Equals(words[ctr2], StringComparison.Ordinal));
}
private static string ShowBytes(string str)
{
string result = null;
foreach (var ch in str)
result += $"{(ushort)ch:X4} ";
return result.Trim();
}
private static string[] NormalizeStrings(NormalizationForm nf, params string[] words)
{
for (int ctr = 0; ctr < words.Length; ctr++)
if (! words[ctr].IsNormalized(nf))
words[ctr] = words[ctr].Normalize(nf);
return words;
}
}
// The example displays the following output:
// sống (0073 1ED1 006E 0067) = sống (0073 00F4 0301 006E 0067): False
// sống (0073 1ED1 006E 0067) = sống (0073 006F 0302 0301 006E 0067): False
// sống (0073 00F4 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): False
//
// Normalization FormC:
//
// sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
// sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
// sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
//
//
// Normalization FormD:
//
// sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
// sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
// sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
//
//
// Normalization FormKC:
//
// sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
// sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
// sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
//
//
// Normalization FormKD:
//
// sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
// sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
// sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
open System
open System.IO
open System.Text
do
use sw = new StreamWriter(@".\TestNorm1.txt")
let showBytes (str: string) =
let mutable result = ""
for ch in str do
result <- result + $"{uint16 ch:X4} "
result.Trim()
let testForEquality (words: string[]) =
for ctr = 0 to words.Length - 2 do
for ctr2 = ctr + 1 to words.Length - 1 do
sw.WriteLine("{0} ({1}) = {2} ({3}): {4}",
words[ctr], showBytes(words[ctr]),
words[ctr2], showBytes(words[ctr2]),
words[ctr].Equals(words[ctr2], StringComparison.Ordinal))
let normalizeStrings nf (words: string[]) =
for i = 0 to words.Length - 1 do
if not (words[i].IsNormalized nf) then
words[i] <- words[i].Normalize nf
words
// Define three versions of the same word.
let s1 = "sống" // create word with U+1ED1
let s2 = "s\u00F4\u0301ng"
let s3 = "so\u0302\u0301ng"
testForEquality [| s1; s2; s3 |]
sw.WriteLine()
// Normalize and compare strings using each normalization form.
for formName in Enum.GetNames typeof<NormalizationForm> do
sw.WriteLine("Normalization {0}:\n", formName)
let nf = Enum.Parse(typeof<NormalizationForm>, formName) :?> NormalizationForm
let sn = normalizeStrings nf [| s1; s2; s3|]
testForEquality sn
sw.WriteLine "\n"
// The example displays the following output:
// sống (0073 1ED1 006E 0067) = sống (0073 00F4 0301 006E 0067): False
// sống (0073 1ED1 006E 0067) = sống (0073 006F 0302 0301 006E 0067): False
// sống (0073 00F4 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): False
//
// Normalization FormC:
//
// sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
// sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
// sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
//
//
// Normalization FormD:
//
// sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
// sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
// sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
//
//
// Normalization FormKC:
//
// sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
// sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
// sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
//
//
// Normalization FormKD:
//
// sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
// sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
// sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
Imports System.Globalization
Imports System.IO
Imports System.Text
Module Example16
Private sw As StreamWriter
Public Sub Main()
sw = New StreamWriter(".\TestNorm1.txt")
' Define three versions of the same word.
Dim s1 As String = "sống" ' create word with U+1ED1
Dim s2 As String = "s" + ChrW(&HF4) + ChrW(&H301) + "ng"
Dim s3 As String = "so" + ChrW(&H302) + ChrW(&H301) + "ng"
TestForEquality(s1, s2, s3)
sw.WriteLine()
' Normalize and compare strings using each normalization form.
For Each formName In [Enum].GetNames(GetType(NormalizationForm))
sw.WriteLine("Normalization {0}:", formName)
Dim nf As NormalizationForm = CType([Enum].Parse(GetType(NormalizationForm), formName),
NormalizationForm)
Dim sn() As String = NormalizeStrings(nf, s1, s2, s3)
TestForEquality(sn)
sw.WriteLine(vbCrLf)
Next
sw.Close()
End Sub
Private Sub TestForEquality(ParamArray words As String())
For ctr As Integer = 0 To words.Length - 2
For ctr2 As Integer = ctr + 1 To words.Length - 1
sw.WriteLine("{0} ({1}) = {2} ({3}): {4}",
words(ctr), ShowBytes(words(ctr)),
words(ctr2), ShowBytes(words(ctr2)),
words(ctr).Equals(words(ctr2), StringComparison.Ordinal))
Next
Next
End Sub
Private Function ShowBytes(str As String) As String
Dim result As String = Nothing
For Each ch In str
result += String.Format("{0} ", Convert.ToUInt16(ch).ToString("X4"))
Next
Return result.Trim()
End Function
Private Function NormalizeStrings(nf As NormalizationForm, ParamArray words() As String) As String()
For ctr As Integer = 0 To words.Length - 1
If Not words(ctr).IsNormalized(nf) Then
words(ctr) = words(ctr).Normalize(nf)
End If
Next
Return words
End Function
End Module
' The example displays the following output:
' sống (0073 1ED1 006E 0067) = sống (0073 00F4 0301 006E 0067): False
' sống (0073 1ED1 006E 0067) = sống (0073 006F 0302 0301 006E 0067): False
' sống (0073 00F4 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): False
'
' Normalization FormC:
'
' sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
' sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
' sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
'
'
' Normalization FormD:
'
' sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
' sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
' sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
'
'
' Normalization FormKC:
'
' sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
' sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
' sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
'
'
' Normalization FormKD:
'
' sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
' sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
' sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
Zie voor meer informatie over normalisatie- en normalisatieformulieren System.Text.NormalizationForm, evenals Unicode-standaardbijlage #15: Unicode-normalisatieformulieren en de veelgestelde vragen over normalisatie op de website van unicode.org.
Stringbewerkingen per categorie
De String klasse biedt leden voor het vergelijken van tekenreeksen, het testen van tekenreeksen voor gelijkheid, het zoeken van tekens of subtekenreeksen in een tekenreeks, het wijzigen van een tekenreeks, het extraheren van subtekenreeksen uit een tekenreeks, het combineren van tekenreeksen, het opmaken van waarden, het kopiëren van een tekenreeks en het normaliseren van een tekenreeks.
Tekenreeksen vergelijken
U kunt tekenreeksen vergelijken om hun relatieve positie in de sorteervolgorde te bepalen met behulp van de volgende String methoden:
Compare retourneert een geheel getal dat de relatie van een tekenreeks aangeeft aan een tweede tekenreeks in de sorteervolgorde.
CompareOrdinal retourneert een geheel getal dat de relatie van één tekenreeks aangeeft aan een tweede tekenreeks op basis van een vergelijking van de bijbehorende codepunten.
CompareTo retourneert een integer die de betrekking van de huidige tekenreeksinstantie tot een tweede tekenreeks in de sorteervolgorde aangeeft. De CompareTo(String) methode biedt de IComparable en IComparable<T> implementaties voor de String klasse.
Strings testen op gelijkheid
U roept de Equals methode aan om te bepalen of twee tekenreeksen gelijk zijn. Met het exemplaar Equals(String, String, StringComparison) en de statische Equals(String, StringComparison) overbelasting kunt u opgeven of de vergelijking cultuurgevoelig of rangschikkend is en of het geval wordt beschouwd of genegeerd. De meeste tests voor gelijkheid zijn ordinair en vergelijkingen voor gelijkheid die de toegang tot een systeemresource (zoals een bestandssysteemobject) bepalen, moeten altijd ordinair zijn.
Tekens zoeken in een tekenreeks
De String klasse bevat twee soorten zoekmethoden:
Methoden die een Boolean waarde retourneren om aan te geven of een bepaalde subtekenreeks aanwezig is in een tekenreeksinstantie. Dit zijn onder andere de Contains, EndsWithen StartsWith methoden.
Methoden die de positie van een subtekenreeks in een tekenreeks aangeven. Dit zijn onder andere de IndexOf, IndexOfAnyen LastIndexOfLastIndexOfAnymethoden.
Waarschuwing
Als u een tekenreeks wilt zoeken naar een bepaald patroon in plaats van een specifieke subtekenreeks, moet u reguliere expressies gebruiken. Zie .NET Regular Expressions voor meer informatie.
Een tekenreeks wijzigen
De String klasse bevat de volgende methoden die de waarde van een tekenreeks wijzigen:
Insert voegt een tekenreeks in het huidige String exemplaar in.
PadLeft voegt een of meer exemplaren van een opgegeven teken aan het begin van een tekenreeks in.
PadRight voegt een of meer exemplaren van een opgegeven teken aan het einde van een tekenreeks in.
Remove verwijdert een subtekenreeks uit het huidige String exemplaar.
Replace vervangt een subtekenreeks door een andere subtekenreeks in het huidige String exemplaar.
ToLower en ToLowerInvariant converteer alle tekens in een tekenreeks naar kleine letters.
ToUpper en ToUpperInvariant converteer alle tekens in een tekenreeks naar hoofdletters.
Trim verwijdert alle voorkomens van een teken aan het begin en het einde van een tekenreeks.
TrimEnd verwijdert alle voorkomens van een teken aan het einde van een tekenreeks.
TrimStart verwijdert alle voorkomens van een teken aan het begin van een tekenreeks.
Belangrijk
Alle methoden voor het wijzigen van tekenreeksen retourneren een nieuw String object. Ze wijzigen de waarde van het huidige exemplaar niet.
Subtekenreeksen extraheren uit een tekenreeks
De String.Split methode scheidt één tekenreeks in meerdere tekenreeksen. Met overbelasting van de methode kunt u meerdere scheidingstekens opgeven, om het aantal subtekenreeksen te beperken dat door de methode wordt geëxtraheerd, witruimte te knippen uit subtekenreeksen en om op te geven of lege tekenreeksen (die voorkomen wanneer scheidingstekens aangrenzend zijn) worden opgenomen in de geretourneerde tekenreeksen.
Tekenreeksen combineren
De volgende String methoden kunnen worden gebruikt voor tekenreekssamenvoeging:
- Concat combineert een of meer subtekenreeksen in één tekenreeks.
- Join voegt een of meer subtekenreeksen samen in één element en voegt een scheidingsteken toe tussen elke subtekenreeks.
Waarden opmaken
De String.Format methode gebruikt de functie samengestelde opmaak om een of meer tijdelijke aanduidingen in een tekenreeks te vervangen door de tekenreeksweergave van een object of waarde. De Format methode wordt vaak gebruikt om het volgende te doen:
- De tekenreeksweergave van een numerieke waarde insluiten in een tekenreeks.
- De tekenreeksweergave van een datum- en tijdwaarde insluiten in een tekenreeks.
- De tekenreeksweergave van een opsommingswaarde insluiten in een tekenreeks.
- Als u de tekenreeksweergave van een bepaald object wilt insluiten dat de IFormattable interface in een tekenreeks ondersteunt.
- Een subtekenreeks in een veld binnen een grotere tekenreeks rechts uitvullen of links uitvullen.
Zie de Format samenvatting over overbelasting voor gedetailleerde informatie over opmaakbewerkingen en voorbeelden.
Een tekenreeks kopiëren
U kunt de volgende String methoden aanroepen om een kopie van een tekenreeks te maken:
- Clone retourneert een verwijzing naar een bestaand String object.
- CopyTo kopieert een deel van een tekenreeks naar een tekenmatrix.
Een tekenreeks normaliseren
In Unicode kan één teken meerdere codepunten bevatten. Normalisatie converteert deze equivalente tekens naar dezelfde binaire weergave. De String.Normalize methode voert de normalisatie uit en de String.IsNormalized methode bepaalt of een tekenreeks is genormaliseerd.
Zie de sectie Normalisatie eerder in dit artikel voor meer informatie en een voorbeeld.