2

Suppose I have the following:

$CUBE_input = "ABC; DEF"

If I perform the following operation,

$($($CUBE_input.ToUpper() -split ';' -replace '(^\s+|\s+$)','' -replace '\s+',' ')[0])

I get ABC, and with [1], I get back DEF (with no leading space thanks to the regex), as expected

However, if I don't have a semicolon split string, e.g.

$CUBE_input = "ABC"

and perform this operation again: $($($CUBE_input.ToUpper() -split ';' -replace '(^\s+|\s+$)','' -replace '\s+',' ')[0])

I get back A

I need to make it so that whether there is a semicolon delimited string or not, it only output the word every time, no characters.

How do I accomplish this?

halfer
  • 19,824
  • 17
  • 99
  • 186
Cataster
  • 3,081
  • 5
  • 32
  • 79

1 Answers1

1

Use (...) instead of $(...), which will result in an array of strings even in the single-element case:

($CUBE_input.ToUpper() -split ';' -replace '(^\s+|\s+$)','' -replace '\s+',' ')[0]

$(...), the subexpression operator is rarely needed outside expandable strings (if you need to embed expression and commands in "..." strings).

Outside of expandable strings, you only need $(...) to embed whole statement(s) (such as if, do, switch, foreach, ...) in a larger expression or command, including providing a statement as the first segment of a pipeline.

In order to embed as single expression or a single command or pipeline in a larger expression or command, use (...), the grouping operator, which avoids the side effects of $(...) - see below.


As for what you tried:

$(...) applies pipeline output logic to the enclosed statements, which means:

  • Arrays resulting from expressions are enumerated and the output objects are then collected, situationally in:

    • a regular [object[]] array, for 2 or more output objects
    • an array element as it itself, in case of a single-element array (if you use @(), the array-subexpression operator instead, you always get an [object[]] array)

Thus, by using $(...), the single-element array produced by -split (and preserved by the -replace operations) was effectively unwrapped, and the element itself - the string 'ABC' - was returned, and applying indices to strings extracts their individual characters; e.g. 'ABC'[0] returns 'A'.

Note that the above also implies that a 2+-element array that is strongly typed is transformed to a new [object[]] array by $(...); e.g.:

PS> $([string[]] ('a', 'b')).GetType().Name
Object[] # !! $(...) enumerated the array and 
         # !! collected the elements in a new [object[]] array

By contrast, (...) returns the expression's value as-is:

PS> ([string[]] ('a', 'b')).GetType().Name
String[] # OK: (...) preserved the array as-is
mklement0
  • 382,024
  • 64
  • 607
  • 775