Daniel Bryson
Daniel Bryson

Reputation: 11

Changing the value of 1 character in a repeating string

All. I have been banging my head off the wall trying to figure this one out.

Lets say I have an array, something like

$array2 = [System.Collections.ArrayList]::new() 

and it has a property called Misc

$array2[$x].Misc

This Variable contains the string "-----"

Based on what the program is doing, I want to update specific spaces on there with different numbers and letters.

so if it does X I want it to say "--X--"
or if it does y I want it to say "-y---"

The only answers I can find are using string.replace, but if all the characters in the string are the same, im not sure how to use it. I've tried making it into a char array and then concatenating it all back together, but I just cant seem to get it to work.

Upvotes: 1

Views: 123

Answers (1)

Doug Maurer
Doug Maurer

Reputation: 8868

You could use regex to replace a certain character.

'-----' -replace '(?<=^.{2}).{1}','X'

--X--

Regex details

  • ^ Start of line anchor
  • (?<=...) Positive look ahead
  • .{n} Match any n characters

As you can see in the output, it replaced one character following two other characters. If you wanted to replace the second character, you would change to

'-----' -replace '(?<=^.{1}).{1}','X'

-X---

This is a great time to make it a function.

Function Set-String {
    Param(
        [string]$InputObject,
        [char]$NewChar,
        [int]$Index
    )

    $after = $Index - 1

    $pattern = "(?<=^.{$after}).{1}"

    $InputObject -replace $pattern,$NewChar

}

You call it like this

Set-String -InputObject '-----' -Index 4 -NewText X

---X-

But if you wanted to replace 2 characters you would have to call it twice. Instead let's improve the function to allow replacing multiple characters. Also add some error handling.

Function Set-String {
    Param(
        [string]$InputObject,
        [string]$NewText,
        [int]$Index
    )

    $after = $Index - 1

    if( $InputObject.Length -lt $NewText.Length ){
        Write-Warning "Replacement text is longer than the input string"
        break
    }
    elseif( ($NewText.Length + $after) -gt $InputObject.Length ){
        Write-Warning "Resulting string would be longer than the input string"
        break
    }

    $pattern = "(?<=^.{$after}).{$($NewText.length)}"

    $InputObject -replace $pattern,$NewText

}

Now you can replace n characters starting at a specific index.

Set-String -InputObject '-----' -Index 2 -NewText X

-X---

Set-String -InputObject '-X---' -Index 2 -NewText -Y

--Y--

Set-String -InputObject '-X-Y-' -Index 3 -NewText XX

-XXX-

Alternatively, if you did make that property an array instead of a string, you could simply use -join to make it a string again and then replace elements at will.

$array = '-----'.ToCharArray()

-join $array

-----

$array[1] = 'X'

-join $array

-X---

$array[1] = '-'
$array[2] = 'Y'

-join $array

--Y--

Upvotes: 1

Related Questions