Formatting, Interpolating, and Escaping Strings
In our previous lesson we learned a bit about how to declare string variable types and initialize them with values. That lesson simplified the initialization of strings because it's actually a little bit confusing the different types of strings that you can create. Let's take a look at the three different types of strings that you can initialize: quoted string literals, verbatim string literals, and raw string literals.
Download this lesson as a Polyglot Notebook to open in Visual Studio Code, or open directly in your web browser with Binder.
Quoted String Literals
String variables can always be declared without setting an initial value. However we can also initialize strings with values such as null or an empty string. We can also declare them with values that are just plain text but things can get a little tricky when we start to integrate and use non alpha numeric characters.
string firstHand; string nullHand = null; string emptyHand = string.Empty; string secondEmptyHand = ""; string fullHouseHand = "2D2C2S5C5D"; display(firstHand);
In the case of the firstHand
and nullHand
, both of these variables are initialized with the value null
. In C# the null
value is a special case that indicates the absence of any value set to the variable. We'll dive further into nulls and handling nulls in a future episode.
The values assigned to emptyHand
and secondEmptyHand
are both equivalent however the double quote value ""
is evaluated by the compiler instead of assigning the constant value string.Empty
This saves just a little bit of processing time to use the string.Empty
constant.
Finally the value assigned to the fullHouseHand
string is a typical quoted string literal. This is the syntax that we expect to see when we're initializing a regular string with alphanumeric text.
We can use additional character sequences to add content including tabs, carriage returns, and even various Unicode characters using a \
escape character.
var myHand = "Fritz\'s Hand"; display(myHand); var myCasinoName = "\"Fritz\'s Casino\""; display(myCasinoName); var sharedCards = "2H\t4C\t5S"; display(sharedCards);
Additionally, emoji are supported values in strings in C# and you can use them effectively to add symbols to your output:
var clubs = "♣️"; var diamonds = "♦️"; var hearts = "♥️"; var spades = "♠️♠"; var flush = "A♠️5♠️6♠️9♠️K♠️"; display(flush);
We'll start using the emoji for the various suits when they are referenced in our cards data going forward.
Verbatim Literals
Verbatim string literals are convenient for multi line strings or strings that contain \
characters. Newline characters and other parts of string text are preserved. To indicate that we're declaring a verbatim string literal, we prefix the quotes with an @
. Some examples:
var windowsFilePath = @"c:\users\Jeff"; var windowsQuotedPath = @"c:\\users\\Jeff"; // According to Bing Chat AI, these are the rules of poker: var rulesOfPoker = @"Poker is a strategic card game where the objective is to create the best hand possible from the cards you’re dealt. The basic rules of poker involve players taking turns to bet, and to stay in the hand and see the next card, all players must have put the same amount of chips in the pot as each other. Actions during a game include checking (declining to bet), folding (withdrawing from the hand if someone else has bet already), betting (placing a wager on the table), raising (adding more chips by matching your opponent’s bet and putting in a greater amount), and calling (matching the bet of your opponents to stay in the hand and continue to play. The player with the highest-ranking hand at the end of the round wins the pot."; display(rulesOfPoker);
Raw String Literals
Brostering literals were introduced as a third way to initialize strings. Allow you to more easily create strings that are multi line, or use any characters that require escape sequences. With rostring literals you don't ever need to use escape sequences. You can just write the string including any white space formatting however you want it to appear in output. There are several rules that you must follow when declaring and using a raw string literal:
- At least three matching double quote characters
"""
are used to start and end the raw string literal. The same number must be used to start and end the value - Single line raw string literals require the opening and closing quote characters on the same line
- Multi-line raw string literals require the opening and closing quote characters to be on their own lines
- Any whitespace to the left of the closing quotes is removed from all lines of the raw string literal. This also means that individual lines before the closing quotes must be indented at least as far from the left as the closing quotes
- Whitespace following the opening quote on the same line is ignored
- Whitespace only lines following the opening quote are included in the string literal
var tableChatter = """Fritz says "hello" to the other players"""; display(tableChatter); var response = """ The other players respond with a hello back to Fritz. Brandy the dealer asks the players to ante up for the first hand. """; display(response);
This also makes formatting values like JSON and XML documents very very easy and readable in C#
var jsonHandFormat = """ { "playerName": "Fritz", "cards": { "A♥️", "A♦️"} } """; var theFlopXml = """ <?xml version="1.0"?> <theFlop> <card suit="♠️" rank="A" /> <card suit="♣️" rank="A" /> <card suit="♠️" rank="5" /> </theFlop> """;
Formatting Strings
Now that we have a better idea of how to declare and initialize strings and even set new values to strings, we can now talk about formatting strings. There are times when you have some templated block of text and you want to be able to insert values from another variable in the middle of that string. It's a little bit clumsy to do that with a Concat
or a +
operator to assemble those values. Fortunately we have the format method available to us that allows us to specify positions inside of our string where we we would like to be able to insert values.
The String.Format
method takes several arguments including the template string and one or more values that you would like to substitute in place of the numeric placeholders in the template. Here's an example:
var theWinner = "Mark"; var winningHand = "7♣️8♠️9♠️10♠️J♥️"; var winnerAnnouncementTemplate = "The winner is {0} with a hand of {1}"; var winner = string.Format(winnerAnnouncementTemplate, theWinner, winningHand); display(winner);
String Interpolation
Formatting strings with this type of template is easy to do however the position and substitution of values later on in the argument is a little bit clumsy for our human eyes to follow. String interpolation was introduced to allow the templated string to include values from variables directly using a similar curly brace notation in the template. Instead of referencing a position for the value inside the curly braces, you can just reference a variable or a value from C# directly. To use this feature, the stream needs to start with a $
prior to the opening "
.
var theWinner = "Mark"; var winningHand = "7♣️8♠️9♠️10♠️J♥️"; var winner = $"The winner is {theWinner} with a hand of {winningHand}"; display(winner);
In formatting strings with either technique, you need to add an extra curly braces characters { }
if you want them to appear in the output:
var theWinner = "Mark"; var winningHand = "7♣️8♠️9♠️10♠️J♥️"; var winner = $"The winner is {theWinner} with a hand of {{ {winningHand} }}"; display(winner);
The same requirement for extra curly brace characters is also in effect for when you're using raw string literals. The number of additional curly braces { }
required to insert a C# value is dictated by the number of dollar signs $$
to start the value. If we want to wrap the winningHand
value with curly braces, we need to add an additional $
character prior to the raw string literal and use two sets of curly braces for every block of text to be interpolated.
You should also notice {theWinner}
does NOT get properly interpolated in the following sample.
var theWinner = "Mark"; var winningHand = "7♣️8♠️9♠️10♠️J♥️"; var winner = $$""" The winner is {theWinner} Their winning hand was: {{{winningHand}}} """; display(winner);