I have a string that contains numerous slashes, for example: $message = ab/cde/f/ghijklm/no/p
I'd like to have a function which when run on this $message
will return a $slash_array
with the values of the position of all the slashes.
ie, in my example above, I would have :
PS > Write-Output $slash_array
3,7,9,17,20
Then I want to use these values to insert a slash after every character except if it's at one of these positions (I don't want the program to add a slash after an already existing slash).
CodePudding user response:
Just loop through the characters and check then return the index
PS C:\> $message = "ab/cde/f/ghijklm/no/p"
PS C:\> $slash_array = for ($i = 0; $i -lt $message.Length; $i )
{ if ($message[$i] -eq '/') { $i 1 } }
PS C:\> $slash_array
3
7
9
17
20
PS C:\> $slash_array -join ', '
3, 7, 9, 17, 20
PS C:\>
But if you just want to insert a slash after any non-slash character why don't just do a regex match then replace?
PS C:\> $message -replace '([^/])(?!/)', '$1/'
a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/
([^/])(?!/)
matches a non-slash character that's not followed by a slash, then add a slash after the matched character
Some other alternatives:
PS C:\> ($message.ToCharArray() | Where-Object { $_ -ne '/' }) -join '/'
a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p
PS C:\> $message.Replace("/", "").ToCharArray() -join '/'
a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p
CodePudding user response:
As Theo points out, since your intent is to separate all individual characters other than a slash (/
) with /
, you don't need to find the indices of existing slashes, because the approach can be simplified to:
removing existing
/
instances, using the-replace
operatorjoining the individual characters in the result with the
-join
operator- The array of individual characters is obtained with the
.ToCharArray()
.NET string method below; alternatively, you could cast to[char[]]
- The array of individual characters is obtained with the
# -> 'a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p'
('ab/cde/f/ghijklm/no/p' -replace '/').ToCharArray() -join '/'
As zett42 points out, the most direct way to obtain - 0
-based - character or substring positions, is to use the [regex]::Matches()
.NET method:
# -> 2, 6, 8, 16, 19
[regex]::Matches('ab/cde/f/ghijklm/no/p', '/').Index
Note that even though the method call returns multiple (a collection of) match-information objects, .Index
can be used to extract the index (position) value from each, courtesy of PowerShell's convenient member-access enumeration feature.