• Aucun résultat trouvé

String literals

Dans le document Bruce PayetteSECOND EDITION (Page 108-113)

Working with types

3.2 B ASIC TYPES AND LITERALS

3.2.1 String literals

There are four kinds of string literals in PowerShell: single-quoted strings, double-quoted strings, single-double-quoted here-strings, and double-double-quoted here-strings. The underlying representation for all of these strings is the same.

String representation in PowerShell

In PowerShell, a string is a sequence of 16-bit Unicode characters and is directly implemented using the .NET System.String type. Because PowerShell strings use Unicode, they can effectively contain characters from every language in the world.

WMI Adapter This adapts objects returned from a WMI provider.

ADO Adapter This adapter allows you to treat the columns in ADO data tables as though they were properties.

Custom Object Adapter

This adapter manages objects for which there’s no actual underlying object, only synthetic properties.

ADSI Object Adapter This adapts objects returned from the Active Directory Service Interfaces.

Table 3.1 The basic set of object adapters available in PowerShell (continued) Adapted object type Description

There are a couple of other characteristics that strings in PowerShell inherit from the underlying .NET strings. They can also be arbitrarily long and they’re immuta-ble—the contents of a string can be copied but can’t be changed without creating an entirely new string.

Single- and double-quoted strings

Because of the expression mode/command mode parsing dichotomy described in chapter 2, strings can be represented in several ways. In expression mode, a string is denoted by a sequence of characters surrounded by matching quotes, as shown in the following example:

PS (1) > "This is a string in double quotes"

This is a string in double quotes

PS (2) > 'This is a string in single quotes' This is a string in single quotes

PS (3) >

Literal strings can contain any character, including newlines, with the exception of an unquoted closing quote character. In double-quoted strings, to embed the closing quote character you have to either quote it with the backtick character or double it up. In other words, two adjacent quotes become a single literal quote in the string. In single-quoted strings, doubling up the quote is the only way to embed a literal quote in the string. This is one area where an important difference exists between single-and double-quoted strings: in single-quoted strings, the backtick isn’t special. This means that it can’t be used for embedding special characters such as newlines or escaping quotes.

Like the Unix shells, PowerShell supports variable substitutions. These variable substitutions or expansions are only done in double-quoted strings (which is why these are sometimes called expandable strings).

Encoding matters

The encoding used in strings is obviously important in international environments. If you’re interested in the nitty-gritty details of the encoding used in System.String, here’s what the Microsoft Developer’s Network documentation has to say:

Each Unicode character in a string is defined by a Unicode scalar value, also called a Unicode code point or the ordinal (numeric) value of the Unicode character. Each code point is encoded using UTF-16 encoding, and the numeric value of each element of the encoding is represented by a Char. The resulting collection of Char objects constitutes the String.

A single Char usually represents a single code point; that is, the numeric value of the Char equals the code point. However, a code point might require more than one encoded element. For example, a Unicode supple-mentary code point (a surrogate pair) is encoded with two Char objects.

Refer to the Microsoft Developer Network (MSDN) documentation for additional details.

BASICTYPESANDLITERALS 79

NOTE Arguments to commands are treated as though they were in double quotes, so variables will be expanded in that situation as well.

You’ll see examples of this later on.

Let’s look at an example of string expansion:

PS (1) > $foo = "FOO"

PS (2) > "This is a string in double quotes: $foo"

This is a string in double quotes: FOO

PS (3) > 'This is a string in single quotes: $foo' This is a string in single quotes: $foo

PS (4) >

In the preceding lines, you can see that $foo in the double-quoted string was replaced by the contents of the variable FOO but not in the single-quoted case.

Subexpression expansion in strings

Expandable strings can also include arbitrary expressions by using the subexpression notation. A subexpression is a fragment of PowerShell script code that’s replaced by the value resulting from the evaluation of that code. Here are examples of subexpres-sion expansubexpres-sion in strings:

PS (1) > "2+2 is $(2+2)"

2+2 is 4 PS (2) > $x=3

PS (3) > "$x * 2 is $($x * 2)"

3 * 2 is 6 PS (4) >

The expression in the $( ... ) sequence in the string is replaced by the result of evaluating the expression. $(2+2) is replaced by 4, and so on.

Using complex subexpressions in strings

So far, these examples show only simple embedded expressions. In fact, subexpres-sions allow statement lists—a series of PowerShell statements separated by semico-lons—to be embedded. Here’s an example where the subexpression contains three simple statements. First execute the three simple statements:

PS (1) > 1;2;3 # three statements 1

2 3

Now execute the same set of statements in a subexpression expansion:

PS (2) > "Expanding three statements in a string: $(1; 2; 3)"

Expanding three statements in a string: 1 2 3 PS (3) >

The result shows the output of the three statements concatenated together, space sep-arated, and inserted into the result string. Here’s another example of using a for statement in a subexpression expansion:

PS (1) > "Numbers 1 thru 10: $(for ($i=1; $i -le 10; $i++) { $i })."

Numbers 1 thru 10: 1 2 3 4 5 6 7 8 9 10.

PS (2) >

The output of all the iterations for the loop are gathered up, turned into a string with one value separated from the next by a space, and then substituted into the overall string. As you can see, this can be quite powerful. Using a subexpression in a string is one way to quickly generate formatted results when presenting data.

String expansion considerations

PowerShell expands strings when an assignment is executed. It doesn’t reevaluate those strings when the variable is used later. This is an important point. Let’s look at two examples that will make this clear. These examples use the postincrement opera-tor ++, which adds 1 to a variable, and the range operator, which expands to a sequence of numbers.

In the first example, initialize $x to 0 and then assign a string with an expansion that increments $x to a variable $a. Next output $a three times to see what happens to the value of $x:

PS (1) > $x=0

PS (2) > $a = "x is $($x++; $x)"

PS (4) > 1..3 | foreach {$a}

x is 1 x is 1 x is 1

As you can see, $x was incremented once when $a was assigned but didn’t change on subsequent references. Now inline the string literal into the body of the loop and see what happens:

PS (5) > 1..3 | foreach {"x is $($x++; $x)"}

x is 1 x is 2 x is 3

This time around, you can see that $x is being incremented each time. To reiterate, string literal expansion is done only when the literal is assigned.

NOTE There’s a way to force a string to be expanded if you need to do it. You can do this by calling $ExecutionContext.InvokeCom-mand.ExpandString( 'a is $a' ). This method will return a new string with all the variables expanded.

Here-string literals

Getting back to the discussion of literal string notation, there’s one more form of string literal, called a here-string. A here-string is used to embed large chunks of text

BASICTYPESANDLITERALS 81 inline in a script. This can be powerful when you’re generating output for another program. Here’s an example that assigns a here-string to the variable $a:

PS (1) > $a = @" looks a lot like PowerShell here-strings. In practice, the C# feature is most like PowerShell’s single-quoted strings. In PowerShell, a here-string begins at the end of the line and the terminating sequence must be at the beginning of the line that terminates the here-string. In C#, the string terminates at the first closing quote that isn’t doubled up.

When $a is displayed, it contains all the lines that were entered. Now you’re probably saying, “Wait a minute—you told me I can do the same thing with a regular string.

What makes here-strings so special?” It has to do with how quoting is handled. Here-strings have special quoting rules.

Here-strings start with @<quote><newline> and end with <newline><quote>@. The <newlines> are important because the here-string quote sequences won’t be treated as quotes without them. The content of the here-string is all the lines between the beginning and ending quotes but not the lines the quotes are on. Because of the fancy opening and closing quote sequences, other special characters (such as quotes that would cause problems in regular strings) are fine here. This makes it easy to gen-erate string data without having quoting errors. Here’s a more elaborate example:

PS (1) > $a = @"

>> One is "1"

>> Two is '2'

>> Three is $(2+1)

>> The date is "$(get-date)"

>> "@ + "A trailing line"

>>

PS (2) > $a One is "1"

Two is '2' Three is 3

The date is "1/8/2006 9:59:16 PM"A trailing line PS (3) >

On line 1, the here-string is assigned to the variable $a. The contents of the here-string start on line 2, which has a here-string containing double quotes. Line 3 has a here-string with single quotes. Line 4 has an embedded expression, and line 5 calls the Get-Date

cmdlet in a subexpression to embed the current date into the string. Finally, line 6 appends some trailing text to the whole string. When you look at the output of the variable shown in lines 9–12, you see that the quotes are all preserved and the expan-sions are shown in place.

Here-strings come in single and double-quoted versions just like regular strings, with the significant difference being that variables and subexpressions aren’t expanded in the single-quoted variant, as shown here:

PS (1) > $a=123 PS (2) > @"

>> a is $a

>> "@

>>

a is 123

In the double-quoted here-string, the variable $a is expanded, but in the single-quoted here-string

PS (3) > @'

>> a is $a

>> '@

>>

a is $a PS (4) >

it isn’t. The single-quoted version is best for embedding large blocks of literal text where you don’t want to have to deal with individually quoting $ everywhere. You’ll see how useful this can be when we look at the Add-Type cmdlet in chapter 9.

That should be enough about strings for now. Let’s move on to numbers and numeric literals. This will finally let us express that “10 MB” value we wanted to compare against earlier.

Dans le document Bruce PayetteSECOND EDITION (Page 108-113)