So how many times do you sit at your desk thinking “How can I easily reverse this string output?”. Probably not at all. But in the case where I needed to do this while working on a future article, I wanted to figure out an easy way to accomplish this with little to no work involved.
There are a couple of different ways to accomplish this and I will show you each of those ways. In the end, I chose going the RegEx route because it felt simpler to work with (not that the other way wasn’t much harder).
The Non-RegEx way
For this I just split out the string into an array.
$string = "This is a test, hope it works!" $arr = $string -split ""
That’s a start, but we still need to still find out how to reverse everything. Luckily, [array] has a static method named… you guessed it, Reverse().
[array]::Reverse($arr) $arr
Lastly, we need to bring everything back on one line.
$arr -join ''
Now that wasn’t too bad. But there is another way to accomplish using Regular Expressions, which I prefer.
RegEx way
Now for the regular expression way. This is basically done with one line, although in this case I set up the string in the first line.
$String = "This is a test, hope it works!" ([regex]::Matches($String,'.','RightToLeft') | ForEach {$_.value}) -join ''
As you can see, it easily takes the string and reverses it using a regular expression. I chose to use the [regex] type accelerator with the Matches() static method to make this happen. I give 3 inputs into the method: String, Pattern, Options.
For the pattern, since I want everything to get matched, I simply use the period (.) to match everything. In order to get the reverse order of all of my matches, I set the Regex options for RightToLeft, which specifies that the search will be from right to left instead of from left to right.
Here is what it looks like just showing the matches:
$String = "This is a test, hope it works!" ([regex]::Matches($String,'.','RightToLeft'))
Using ForEach looping can only grabbing the values ($_.Value), I then do use the –join operator to bring everything back together in reverse order as a single string as shown earlier.
Like I said before, I cannot think of a good use case for reversing a string, but I am sure they are out there. If you happen to have one, feel free to leave it in the comments! Because I figured someone out there might like a function to reverse strings, I put this together called Out-ReverseString. It takes a single or a collection of strings and provides the reverse string as its output.
Function Out-ReverseString { <# .SYNOPSIS Reverses a string .DESCRIPTION Reverses a string .PARAMETER String String input that will be reversed .NOTES Author: Boe Prox Date Created: 12August2012 .OUTPUT System.String .EXAMPLE Out-ReverseString -String "This is a test of a string!" !gnirts a fo tset a si sihT Description ----------- Reverses a string input. .EXAMPLE [string[]]$Strings = "Simple string","Another string","1 2 3 4 5 6" $Strings | Out-ReverseString gnirts elpmiS gnirts rehtonA 6 5 4 3 2 1 Description ----------- Takes a collection of strings and reverses each string. #> [cmdletbinding()] Param ( [parameter(Mandatory=$True,ValueFromPipeline=$True)] [HelpMessage("Enter a String or collection of Strings")] [ValidateNotNullOrEmpty()] [string[]]$String ) Process { ForEach ($Item in $String) { ([regex]::Matches($Item,'.','RightToLeft') | ForEach {$_.value}) -join '' } } }
#Sorted distinguishedname list
$OUs = (Get-ADOrganizationalUnit -Filter *).distinguishedname | foreach-object{($_ -split “,”)[-1..-42] -join ‘,’ }| sort | foreach-object{($_ -split “,”)[-1..-42] -join ‘,’ }
And I’m back (to report another use case). Another closely related use case would be if you have PTR records like “100.1.1.10.in-addr.arpa”, and you want the “normal” IP (10.1.1.100). There might be some .NET method for this, come to think about it, but I wouldn’t be surprised if there isn’t either?
Anyway, doing it with string manipulation, you could do something like this to reverse the IP segments/octets and strip off the in-addr.arpa domain:
PS D:\> $PTR = “100.1.1.10.in-addr.arpa”
PS D:\> $t = $PTR -replace ‘.in-addr.arpa$’ -split ‘.’
PS D:\> $IP = $t[-1..-($t.Count)] -join ‘.’
PS D:\> $IP
10.1.1.100
PS D:\>
As for the use case, I have one which lead me to this article, namely having a CSV file with computer names and their corresponding AD DNs (LDAP distinguished name) and wanting to sort them by DN. If you consider what a DN looks like, you’ll soon realize that sorting it normally won’t work well, not even if you cut off the “CN=…” part first, and that sorting it backwards is perfect for categorizing by DN visually in the output.
Example DN:
CN=computer,OU=foo,OU=bar,DC=ad,DC=example,DC=com
I liked Rich Prescott’s suggestion mostly for the sake of the sheer brevity.
This is the line that gave me what I wanted:
ipcsv -delim ‘;’ .\tmp.csv | sort @{e={ $_.DN[-1..-($_.DN.Length)] -join ” }}, ComputerName | ft -a
Here’s another way:
$str = “This is a test, hope it works!”
$str[-1..-($str.length)] -join ”
I tried this and it seems to be missing a ”
$str[-1..-($str.length)] -join ””
Now that is a clever expression.
Use case: function collecting suffixes in serial numbers.
Cool. Another option would be using string indexing:
$str = “This is a test, hope it works!”
-join (($str.length-1)..0 | Foreach-Object { $str[$_] })
Awesome! Thanks, Shay!
here is another one with foreach-object using begin, process, end.
“This is a test, hope it works!” -split “” | ForEach-Object -Begin {$a = @()} -Process {$a = $_ + $a} -End {$a}