Delen via


Letterlijke tekenreeksen en tekenreeksen

Een tekenreeks is een object van het type String waarvan de waarde tekst is. Intern wordt de tekst opgeslagen als een sequentiële verzameling Char objecten met het kenmerk Alleen-lezen. De Length eigenschap van een tekenreeks vertegenwoordigt het aantal Char objecten dat deze bevat, niet het aantal Unicode-tekens. Gebruik het StringInfo object om toegang te krijgen tot de afzonderlijke Unicode-codepunten in een tekenreeks.

String versus System.String

In C# is het string trefwoord een alias voor String; daarom String en string zijn ze gelijkwaardig. Gebruik de opgegeven alias string zoals deze werkt, zelfs zonder using System;. De String klasse biedt veel methoden voor het veilig maken, bewerken en vergelijken van tekenreeksen. Bovendien overbelast de C#-taal sommige operators om algemene tekenreeksbewerkingen te vereenvoudigen. Zie string voor meer informatie over het trefwoord. Zie voor meer informatie over het type en de bijbehorende methoden String.

Tekenreeksen declareren en initialiseren

U kunt tekenreeksen op verschillende manieren declareren en initialiseren, zoals wordt weergegeven in het volgende voorbeeld:

// Declare without initializing.
string message1;

// Initialize to null.
string? message2 = null;

// Initialize as an empty string.
// Use the Empty constant instead of the literal "".
string message3 = System.String.Empty;

// Initialize with a regular string literal.
string oldPath = "c:\\Program Files\\Microsoft Visual Studio 8.0";

// Initialize with a verbatim string literal.
string newPath = @"c:\Program Files\Microsoft Visual Studio 9.0";

// Use System.String if you prefer.
System.String greeting = "Hello World!";

// In local variables (i.e. within a method body)
// you can use implicit typing.
var temp = "I'm still a strongly-typed System.String!";

// Use a const string to prevent 'message4' from
// being used to store another string value.
const string message4 = "You can't get rid of me!";

// Use the String constructor only when creating
// a string from a char*, char[], or sbyte*. See
// System.String documentation for details.
char[] letters = { 'A', 'B', 'C' };
string alphabet = new string(letters);

U gebruikt de nieuwe operator niet om een tekenreeksobject te maken, behalve wanneer u de tekenreeks initialiseert met een matrix met tekens.

Initialiseer een tekenreeks met de Empty constante waarde om een nieuw String object te maken waarvan de tekenreeks de lengte nul heeft. De letterlijke tekenreeksweergave van een tekenreeks met lengte nul is "". Door tekenreeksen te initialiseren met de Empty waarde in plaats van null, kunt u de kans op een NullReferenceException gebeurtenis verminderen. Gebruik de statische IsNullOrEmpty(String) methode om de waarde van een tekenreeks te controleren voordat u deze probeert te openen.

Onveranderbaarheid van tekenreeksen

Tekenreeksobjecten kunnen onveranderbaar zijn: ze kunnen niet worden gewijzigd nadat ze zijn gemaakt. String Alle methoden en C#-operators die een tekenreeks lijken te wijzigen, retourneren daadwerkelijk de resultaten in een nieuw tekenreeksobject. In het volgende voorbeeld worden de twee oorspronkelijke tekenreeksen ongewijzigd wanneer de inhoud van s1 en s2 worden samengevoegd om één tekenreeks te vormen. De += operator maakt een nieuwe tekenreeks die de gecombineerde inhoud bevat. Dit nieuwe object wordt toegewezen aan de variabele s1, en het oorspronkelijke object dat was toegewezen aan s1, wordt vrijgegeven voor garbage collection omdat er geen andere variabele een verwijzing naar heeft.

string s1 = "A string is more ";
string s2 = "than the sum of its chars.";

// Concatenate s1 and s2. This actually creates a new
// string object and stores it in s1, releasing the
// reference to the original object.
s1 += s2;

System.Console.WriteLine(s1);
// Output: A string is more than the sum of its chars.

Omdat een tekenreeks 'wijzigen' eigenlijk een nieuwe tekenreeks is, moet u voorzichtig zijn bij het maken van verwijzingen naar tekenreeksen. Als u een verwijzing naar een tekenreeks maakt en vervolgens de oorspronkelijke tekenreeks wijzigt, blijft de verwijzing verwijzen naar het oorspronkelijke object in plaats van het nieuwe object dat is gemaakt toen de tekenreeks werd gewijzigd. De volgende code illustreert dit gedrag:

string str1 = "Hello ";
string str2 = str1;
str1 += "World";

System.Console.WriteLine(str2);
//Output: Hello

Zie De inhoud van tekenreeksen wijzigen voor meer informatie over het maken van nieuwe tekenreeksen die zijn gebaseerd op wijzigingen zoals zoek- en vervangingsbewerkingen op de oorspronkelijke tekenreeks.

Geciteerde letterlijke tekenreeksen

Letterlijke tekenreeksen tussen aanhalingstekens beginnen en eindigen met één dubbel aanhalingsteken (") op dezelfde regel. Letterlijke tekenreeksen tussen aanhalingstekens zijn het meest geschikt voor tekenreeksen die op één regel passen en geen escapereeksen bevatten. Een letterlijke tekenreeks tussen aanhalingstekens moet escapetekens insluiten, zoals wordt weergegeven in het volgende voorbeeld:

string columns = "Column 1\tColumn 2\tColumn 3";
//Output: Column 1        Column 2        Column 3

string rows = "Row 1\r\nRow 2\r\nRow 3";
/* Output:
    Row 1
    Row 2
    Row 3
*/

string title = "\"The \u00C6olean Harp\", by Samuel Taylor Coleridge";
//Output: "The Æolean Harp", by Samuel Taylor Coleridge

Letterlijke letterreeksen

Verbatim stringliteralen zijn handiger voor meerregelige tekenreeksen, tekens die backslashtekens of ingesloten dubbele aanhalingstekens bevatten. Bij verbatimtekenreeksen blijven nieuwe regeltekens behouden als onderdeel van de tekst. Gebruik dubbele aanhalingstekens om een aanhalingsteken in te sluiten binnen een letterlijke tekenreeks. In het volgende voorbeeld ziet u enkele veelvoorkomende toepassingen voor verbatimtekenreeksen:

string title = "\"The \u00C6olean Harp\", by Samuel Taylor Coleridge";
//Output: "The Æolean Harp", by Samuel Taylor Coleridge

string filePath = @"C:\Users\scoleridge\Documents\";
//Output: C:\Users\scoleridge\Documents\

string text = @"My pensive SARA ! thy soft cheek reclined
    Thus on mine arm, most soothing sweet it is
    To sit beside our Cot,...";
/* Output:
My pensive SARA ! thy soft cheek reclined
    Thus on mine arm, most soothing sweet it is
    To sit beside our Cot,...
*/

string quote = @"Her name was ""Sara.""";
//Output: Her name was "Sara."

Ruwe letterlijke tekenreeksen

Vanaf C# 11 kunt u onbewerkte letterlijke tekenreeksen gebruiken om makkelijkere tekenreeksen te maken die uit meerdere regels bestaan of om tekens te gebruiken die escapereeksen vereisen. Onbewerkte letterlijke tekenreeksen maken het overbodig om ooit escapevolgorden te gebruiken. U kunt de tekenreeks schrijven, inclusief witruimteopmaak, hoe u deze in de uitvoer wilt weergeven. Een onbewerkte string literal:

  • Begint en eindigt met een reeks van ten minste drie dubbele aanhalingstekens ("""). U kunt meer dan drie opeenvolgende tekens gebruiken om de reeks te starten en te beëindigen om letterlijke tekenreeksen te ondersteunen die drie (of meer) herhaalde aanhalingstekens bevatten.
  • Enkelregelige letterlijke tekenreeksen vereisen dat de openings- en sluitende aanhalingstekens zich op dezelfde regel bevinden.
  • Letterlijke tekenreeksen met meerdere regels vereisen dat zowel de openings- als de afsluitingsaanhalingstekens op een eigen regel staan.
  • In letterlijke tekenreeksen met meerdere regels wordt elke witruimte links van de afsluitende aanhalingstekens verwijderd uit alle regels van de letterlijke tekenreeks.
  • In meerregelige letterlijke tekenreeksen wordt witruimte na het openingsaanhalingsteken op dezelfde regel genegeerd.
  • In onbewerkte meerregelige letterlijke tekenreeksen worden witruimte alleen lijnen die volgen op het openingsaanhalingsteken opgenomen in de letterlijke tekenreeks.

In de volgende voorbeelden ziet u de volgende regels:

string singleLine = """Friends say "hello" as they pass by.""";
string multiLine = """
    "Hello World!" is typically the first program someone writes.
    """;
string embeddedXML = """
       <element attr = "content">
           <body style="normal">
               Here is the main text
           </body>
           <footer>
               Excerpts from "An amazing story"
           </footer>
       </element >
       """;
// The line "<element attr = "content">" starts in the first column.
// All whitespace left of that column is removed from the string.

string rawStringLiteralDelimiter = """"
    Raw string literals are delimited 
    by a string of at least three double quotes,
    like this: """
    """";

In de volgende voorbeelden worden de compilerfouten gedemonstreerd die zijn gerapporteerd op basis van deze regels:

// CS8997: Unterminated raw string literal.
var multiLineStart = """This
    is the beginning of a string 
    """;

// CS9000: Raw string literal delimiter must be on its own line.
var multiLineEnd = """
    This is the beginning of a string """;

// CS8999: Line does not start with the same whitespace as the closing line
// of the raw string literal
var noOutdenting = """
    A line of text.
Trying to outdent the second line.
    """;

De eerste twee voorbeelden zijn ongeldig omdat letterlijke tekenreeksen met meerdere regels vereisen dat de openings- en sluitende aanhalingstekens op een eigen regel staan. Het derde voorbeeld is ongeldig omdat de tekst is afgeleid van de afsluitende aanhalingstekenreeks.

Overweeg onbewerkte tekenreeksen te gebruiken wanneer u tekst genereert die tekens bevat waarvoor escapereeksen zijn vereist bij het gebruik van geciteerde tekenreeksen of verbatim tekenreeksen. Ruwe string-literals zijn gemakkelijker voor jou en anderen om te lezen, omdat zij meer lijken op de uitvoertekst. Denk bijvoorbeeld aan de volgende code die een tekenreeks met opgemaakte JSON bevat:

string jsonString = """
{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": "Hot",
  "DatesAvailable": [
    "2019-08-01T00:00:00-07:00",
    "2019-08-02T00:00:00-07:00"
  ],
  "TemperatureRanges": {
    "Cold": {
      "High": 20,
      "Low": -10
    },
    "Hot": {
      "High": 60,
      "Low": 20
    }
            },
  "SummaryWords": [
    "Cool",
    "Windy",
    "Humid"
  ]
}
""";

Escapesequenties voor tekenreeksen

Escape-sequentie Karakternaam Unicode-codering
\' Enkele aanhalingsteken 0x0027
\" Dubbele aanhalingstekens 0x0022
\\ Backslash 0x005C
\0 Nul 0x0000
\a Waarschuwing 0x0007
\b Backspatie 0x0008
\e Ontsnappen 0x001B
\f Formulierfeed 0x000C
\n Nieuwe regel 0x000A
\r Regelterugloop 0x000D
\t Horizontaal tabblad 0x0009
\v Verticaal tabblad 0x000B
\u Unicode-escapevolgorde (UTF-16) \uHHHH (bereik: 0000 - FFFF; voorbeeld: \u00E7 = "ç")
\U Unicode-ontsnapreeks (UTF-32) \U00HHHHHH (bereik: 000000 - 10FFFF; voorbeeld: \U0001F47D = "👽")
\x Unicode-escapereeks vergelijkbaar met \u, behalve met variabele lengte \xH[H][H][H] (bereik: 0 - FFFF; voorbeeld: \x00E7 of \x0E7\xE7 = "ç")

Waarschuwing

Wanneer u de \x-escapereeks gebruikt en minder dan 4 hex-cijfers opgeeft, zullen, indien de tekens die onmiddellijk na de escapereeks komen geldige hexadecimale cijfers zijn (dat wil zeggen 0-9, A-F en a-f), deze worden geïnterpreteerd als onderdeel van de escapereeks. Produceert bijvoorbeeld \xA1 '¡', wat codepunt U+00A1 is. Als het volgende teken echter 'A' of 'a' is, wordt de escapereeks geïnterpreteerd als '\xA1A' en produceert het 'ਚ', wat overeenkomt met codepunt U+0A1A. Als u in dergelijke gevallen alle vier hexcijferige cijfers (bijvoorbeeld) opgeeft, \x00A1voorkomt u mogelijke onjuiste interpretatie.

Opmerking

Tijdens het compileren worden verbatim- en onbewerkte tekenreeksen geconverteerd naar gewone tekenreeksen met dezelfde escapereeksen. Als u daarom een exacte of onbewerkte tekenreeks bekijkt in het venster van het foutopsporingsprogramma, ziet u de escapetekens die zijn toegevoegd door de compiler, niet de exacte of onbewerkte versie van uw broncode. De exacte tekenreeks @"C:\files.txt" wordt bijvoorbeeld weergegeven in het bekijkvenster als "C:\\files.txt".

Tekenreeksen opmaken

Een notatietekenreeks is een tekenreeks waarvan de inhoud dynamisch wordt bepaald tijdens runtime. Opmaaktekenreeksen worden gecreëerd door in een tekenreeks geïnterpoleerde expressies of tijdelijke aanduidingen tussen accolades in te voegen. Alles binnen de accolades ({...}) wordt omgezet naar een waarde en uitgevoerd als een opgemaakte string tijdens de uitvoering. Er zijn twee methoden om opmaaktekenreeksen te maken: tekenreeksinterpolatie en samengestelde opmaak.

Tekenreeksinterpolatie

U declareert geïnterpoleerde tekenreeksen met het $ speciale teken. Een geïnterpoleerde tekenreeks bevat geïnterpoleerde expressies in haakjes. Als u nieuw bent met tekenreeksinterpolatie, bekijk dan de zelfstudie Tekenreeksinterpolatie - C# voor verschillende voorbeelden.

Gebruik tekenreeksinterpolatie om de leesbaarheid en onderhoudbaarheid van uw code te verbeteren. Tekenreeksinterpolatie bereikt dezelfde resultaten als de String.Format-methode, maar is gemakkelijker te gebruiken en verbetert de duidelijkheid in de code.

var jh = (firstName: "Jupiter", lastName: "Hammon", born: 1711, published: 1761);
Console.WriteLine($"{jh.firstName} {jh.lastName} was an African American poet born in {jh.born}.");
Console.WriteLine($"He was first published in {jh.published} at the age of {jh.published - jh.born}.");
Console.WriteLine($"He'd be over {Math.Round((2018d - jh.born) / 100d) * 100d} years old today.");

// Output:
// Jupiter Hammon was an African American poet born in 1711.
// He was first published in 1761 at the age of 50.
// He'd be over 300 years old today.

U kunt tekenreeksinterpolatie gebruiken om een constante tekenreeks te initialiseren wanneer alle expressies die worden gebruikt voor tijdelijke aanduidingen ook constante tekenreeksen zijn.

Vanaf C# 11 kunt u letterlijke tekenreeksen combineren met tekenreeksinterpolaties. U begint en beëindigt de notatietekenreeks met drie of meer opeenvolgende dubbele aanhalingstekens. Als de uitvoertekenreeks het { of } teken moet bevatten, kunt u extra $ tekens gebruiken om op te geven hoeveel { tekens en } tekens een interpolatie beginnen en beëindigen. Elke reeks van minder { tekens of } tekens wordt opgenomen in de uitvoer. In het volgende voorbeeld ziet u hoe u deze functie kunt gebruiken om de afstand van een punt vanaf de oorsprong weer te geven en het punt tussen accolades te plaatsen:

int X = 2;
int Y = 3;

var pointMessage = $$"""The point {{{X}}, {{Y}}} is {{Math.Sqrt(X * X + Y * Y)}} from the origin.""";

Console.WriteLine(pointMessage);
// Output:
// The point {2, 3} is 3.605551275463989 from the origin.

Interpolatie van verbatimtekenreeks

C# staat ook verbatimtekenreeksinterpolatie toe, bijvoorbeeld over meerdere regels, met behulp van de $@ of @$ syntaxis.

Als u escapereeksen letterlijk wilt interpreteren, gebruikt u een letterlijke tekenreeks. Een geïnterpoleerde verbatimtekenreeks begint met het $ teken gevolgd door het @ teken. U kunt de $ en @ tokens in elke willekeurige volgorde gebruiken: beide $@"..." en @$"..." zijn geldige, geïnterpoleerde verbatimtekenreeksen.

var jh = (firstName: "Jupiter", lastName: "Hammon", born: 1711, published: 1761);
Console.WriteLine($@"{jh.firstName} {jh.lastName}
    was an African American poet born in {jh.born}.");
Console.WriteLine(@$"He was first published in {jh.published}
at the age of {jh.published - jh.born}.");

// Output:
// Jupiter Hammon
//     was an African American poet born in 1711.
// He was first published in 1761
// at the age of 50.

Samengestelde opmaak

Hierbij gebruikt String.Format plaatsaanduidingen in accolades om een formaattekenreeks te maken. Dit voorbeeld resulteert in vergelijkbare uitvoer als de tekenreeksinterpolatiemethode die in het voorgaande voorbeeld wordt gebruikt.

var pw = (firstName: "Phillis", lastName: "Wheatley", born: 1753, published: 1773);
Console.WriteLine("{0} {1} was an African American poet born in {2}.", pw.firstName, pw.lastName, pw.born);
Console.WriteLine("She was first published in {0} at the age of {1}.", pw.published, pw.published - pw.born);
Console.WriteLine("She'd be over {0} years old today.", Math.Round((2018d - pw.born) / 100d) * 100d);

// Output:
// Phillis Wheatley was an African American poet born in 1753.
// She was first published in 1773 at the age of 20.
// She'd be over 300 years old today.

Zie Samengestelde opmaak in .NET voor meer informatie.

Subtekenreeksen

Een substring is een reeks tekens die zich in een tekenreeks bevinden. Gebruik de Substring methode om een nieuwe tekenreeks te maken op basis van een deel van de oorspronkelijke tekenreeks. U kunt zoeken naar een of meer exemplaren van een subtekenreeks met behulp van de IndexOf methode. Gebruik de Replace methode om alle exemplaren van een opgegeven subtekenreeks te vervangen door een nieuwe tekenreeks. Net als bij de Substring methode wordt Replace een nieuwe tekenreeks geretourneerd en wordt de oorspronkelijke tekenreeks niet gewijzigd. Zie Tekenreeksen zoeken en de inhoud van tekenreeksen wijzigen voor meer informatie.

string s3 = "Visual C# Express";
System.Console.WriteLine(s3.Substring(7, 2));
// Output: "C#"

System.Console.WriteLine(s3.Replace("C#", "Basic"));
// Output: "Visual Basic Express"

// Index values are zero-based
int index = s3.IndexOf("C");
// index = 7

Toegang tot afzonderlijke tekens

U kunt matrix-notatie gebruiken met een indexwaarde om alleen-lezentoegang tot afzonderlijke tekens te verkrijgen, zoals in het volgende voorbeeld:

string s5 = "Printing backwards";

for (int i = 0; i < s5.Length; i++)
{
    System.Console.Write(s5[s5.Length - i - 1]);
}
// Output: "sdrawkcab gnitnirP"

Als de String methoden niet de functionaliteit bieden die u nodig hebt om afzonderlijke tekens in een tekenreeks te wijzigen, kunt u een StringBuilder object gebruiken om de afzonderlijke tekens 'in-place' te wijzigen en vervolgens een nieuwe tekenreeks te maken om de resultaten op te slaan met behulp van de StringBuilder methoden. In het volgende voorbeeld wordt ervan uitgegaan dat u de oorspronkelijke tekenreeks op een bepaalde manier moet wijzigen en de resultaten vervolgens moet opslaan voor toekomstig gebruik:

string question = "hOW DOES mICROSOFT wORD DEAL WITH THE cAPS lOCK KEY?";
System.Text.StringBuilder sb = new System.Text.StringBuilder(question);

for (int j = 0; j < sb.Length; j++)
{
    if (System.Char.IsLower(sb[j]) == true)
        sb[j] = System.Char.ToUpper(sb[j]);
    else if (System.Char.IsUpper(sb[j]) == true)
        sb[j] = System.Char.ToLower(sb[j]);
}
// Store the new string.
string corrected = sb.ToString();
System.Console.WriteLine(corrected);
// Output: How does Microsoft Word deal with the Caps Lock key?

Null-tekenreeksen en lege tekenreeksen

Een lege tekenreeks is een exemplaar van een System.String object dat nul tekens bevat. Lege tekenreeksen worden vaak gebruikt in verschillende programmeerscenario's om een leeg tekstveld weer te geven. U kunt methoden aanroepen voor lege tekenreeksen omdat ze geldige System.String objecten zijn. Lege tekenreeksen worden als volgt geïnitialiseerd:

string s = String.Empty;

Een null-tekenreeks verwijst daarentegen niet naar een exemplaar van een System.String object en een poging om een methode aan te roepen voor een null-tekenreeks veroorzaakt een NullReferenceException. U kunt echter null-tekenreeksen gebruiken in samenvoegings- en vergelijkingsbewerkingen met andere tekenreeksen. In de volgende voorbeelden ziet u enkele gevallen waarin een verwijzing naar een null-tekenreeks wel en niet tot gevolg heeft dat er een uitzondering wordt gegenereerd:

string str = "hello";
string? nullStr = null;
string emptyStr = String.Empty;

string tempStr = str + nullStr;
// Output of the following line: hello
Console.WriteLine(tempStr);

bool b = (emptyStr == nullStr);
// Output of the following line: False
Console.WriteLine(b);

// The following line creates a new empty string.
string newStr = emptyStr + nullStr;

// Null strings and empty strings behave differently. The following
// two lines display 0.
Console.WriteLine(emptyStr.Length);
Console.WriteLine(newStr.Length);
// The following line raises a NullReferenceException.
//Console.WriteLine(nullStr.Length);

// The null character can be displayed and counted, like other chars.
string s1 = "\x0" + "abc";
string s2 = "abc" + "\x0";
// Output of the following line: * abc*
Console.WriteLine("*" + s1 + "*");
// Output of the following line: *abc *
Console.WriteLine("*" + s2 + "*");
// Output of the following line: 4
Console.WriteLine(s2.Length);

StringBuilder gebruiken voor het snel maken van tekenreeksen

Tekenreeksbewerkingen in .NET zijn sterk geoptimaliseerd en hebben in de meeste gevallen geen invloed op de prestaties. In sommige scenario's, zoals intensieve loops die vele honderden of duizenden keren worden uitgevoerd, kunnen stringbewerkingen echter van invloed zijn op de prestaties. De StringBuilder klasse maakt een tekenreeksbuffer die betere prestaties biedt als uw programma veel tekenreeksbewerkingen uitvoert. Met StringBuilder de tekenreeks kunt u ook afzonderlijke tekens opnieuw toewijzen, iets wat het ingebouwde tekenreeksgegevenstype niet ondersteunt. Met deze code wordt bijvoorbeeld de inhoud van een tekenreeks gewijzigd zonder een nieuwe tekenreeks te maken:

System.Text.StringBuilder sb = new System.Text.StringBuilder("Rat: the ideal pet");
sb[0] = 'C';
System.Console.WriteLine(sb.ToString());
//Outputs Cat: the ideal pet

In dit voorbeeld wordt een StringBuilder object gebruikt om een tekenreeks te maken uit een set van numerieke typen.

var sb = new StringBuilder();

// Create a string composed of numbers 0 - 9
for (int i = 0; i < 10; i++)
{
    sb.Append(i.ToString());
}
Console.WriteLine(sb);  // displays 0123456789

// Copy one character of the string (not possible with a System.String)
sb[0] = sb[9];

Console.WriteLine(sb);  // displays 9123456789

Tekenreeksen, extensiemethoden en LINQ

Omdat het String-type IEnumerable<T> implementeert, kunt u de extensiemethoden gebruiken die zijn gedefinieerd in de Enumerable klasse op strings. Om onbelangrijke visuals te voorkomen, worden deze methoden uitgesloten van IntelliSense voor het String type, maar ze zijn toch beschikbaar. U kunt ook LINQ-queryexpressies gebruiken voor tekenreeksen. Zie LINQ en Tekenreeksen voor meer informatie.