Yeah, this is deceptively difficult to do correctly.
It’s a little complicated to reverse a word correctly if you need to support multicharacter glyphs.
Let’s take a string, and then convert it to use multicharacter accents, and then reverse it:
$S = 'éa'
$MCString = $S.Normalize([System.Text.NormalizationForm]::FormD)
$MCCharArr = $MCString.ToCharArray()
[System.Array]::Reverse($MCCharArr)
-join $MCCharArr
Will output:
áe
The accent is now on the a
instead of the e
, so that’s wrong. Lots of languages have glyphs that only work like this, so many Unicode sequences can’t be reversed by a simple character array reverse.
But C# does contain Unicode libraries to process this information. Be aware that emoji and other newer characters have been known to be buggy even in some versions of .Net Core.
# Create a string and force it to use multicharacter glyphs.
$OriginalString = 'Maireann croí éadrom a bhfad.'.Normalize([System.Text.NormalizationForm]::FormD)
# Get the globalization stringinfo so we can enumerate it for each
$OriginalStringInfo = New-Object -TypeName System.Globalization.StringInfo -ArgumentList $OriginalString
# Create a StringBuilder for the new string
$SB = New-Object -TypeName System.Text.StringBuilder -ArgumentList $OriginalString.Length
# Iterate through each text element in reverse order
($OriginalStringInfo.LengthInTextElements-1)..0 | ForEach-Object { [void]$SB.Append($OriginalStringInfo.SubstringByTextElements($_,1)) }
# Convert the StringBuilder to a string, and then use single-character glyphs where possible
$NewString = $SB.ToString().Normalize([System.Text.NormalizationForm]::FormC)
The value of $NewString
should be .dafhb a mordaé íorc nnaeriaM
.
If, on the other hand, the correct output is supposed to be nnaeriaM íorc mordaé a dafhb.
then it gets… really complicated.
November 4th, 2015
Summary: Ed Wilson, Microsoft Scripting Guy, talks about using Windows PowerShell to reverse strings.
Hey, Scripting Guy! I am working with Windows PowerShell, and I need to reverse a string. I am surprised there is no reverse method in the string class. It seems like a major oversight. Anyway, can you show me how to do this easily?
—SS
Hello SS,
Microsoft Scripting Guy, Ed Wilson, is here. This week is an awesome week. The MVP Summit is going on, and the Scripting Wife is in Bellevue/Redmond/Seattle hanging with thousands of MVPs from around the world. She keeps sending me text messages, like, “Dude, I just got to see Jaap,” and “I was talking to Mark,” and “Guess what? Karl is coming to the get-together tonight.” One was, “You are not going to believe it. Vlad invited me to sit in on the Jeremy unplugged session! OMG!!!”
I mean, it is nearly a real-time stream of messages. Then she goes quiet when she is in an NDA session.
Nah, I am not jealous. Nope. Not one bit…
So, SS. I was sitting on the patio overlooking the pool, and I was sipping a nice cup of English Breakfast tea. I have rather poor WiFi, but I turned on Internet Connection Sharing on my Windows 8.1 phone, and boom! My Windows 10 laptop joined the connection and all is good. Actually, the performance is really quite good. I might watch Buffy the Vampire Slayer this evening on Netflix. Yeah, no reason not to. This is working out really well. I digress…
So you have a string. I’ll store the string in a variable named $a. I then display the contents of the $a variable. This is shown here:
PS d:> $a = “abcde”
PS d:> $a
Abcde
I know that I have a System.String, and I can look this up by using the Get-Member cmdlet. I pipe the $a variable to Get-Member (gm is an alias) and look through the methods and properties associated with the string object:
PS d:> $a | gm
TypeName: System.String
Name MemberType Definition
—- ———- ———-
Clone Method System.Object Clone(), System.Object ICloneable.Clone()
CompareTo Method int CompareTo(System.Object value), int CompareTo(string strB), int IComparab…
Contains Method bool Contains(string value)
CopyTo Method void CopyTo(int sourceIndex, char[] destination, int destinationIndex, int co…
EndsWith Method bool EndsWith(string value), bool EndsWith(string value, System.StringCompari…
Equals Method bool Equals(System.Object obj), bool Equals(string value), bool Equals(string…
GetEnumerator Method System.CharEnumerator GetEnumerator(), System.Collections.IEnumerator IEnumer…
GetHashCode Method int GetHashCode()
GetType Method type GetType()
GetTypeCode Method System.TypeCode GetTypeCode(), System.TypeCode IConvertible.GetTypeCode()
IndexOf Method int IndexOf(char value), int IndexOf(char value, int startIndex), int IndexOf…
IndexOfAny Method int IndexOfAny(char[] anyOf), int IndexOfAny(char[] anyOf, int startIndex), i…
Insert Method string Insert(int startIndex, string value)
IsNormalized Method bool IsNormalized(), bool IsNormalized(System.Text.NormalizationForm normaliz…
LastIndexOf Method int LastIndexOf(char value), int LastIndexOf(char value, int startIndex), int…
LastIndexOfAny Method int LastIndexOfAny(char[] anyOf), int LastIndexOfAny(char[] anyOf, int startI…
Normalize Method string Normalize(), string Normalize(System.Text.NormalizationForm normalizat…
PadLeft Method string PadLeft(int totalWidth), string PadLeft(int totalWidth, char paddingChar)
PadRight Method string PadRight(int totalWidth), string PadRight(int totalWidth, char padding…
Remove Method string Remove(int startIndex, int count), string Remove(int startIndex)
Replace Method string Replace(char oldChar, char newChar), string Replace(string oldValue, s…
Split Method string[] Split(Params char[] separator), string[] Split(char[] separator, int…
StartsWith Method bool StartsWith(string value), bool StartsWith(string value, System.StringCom…
Substring Method string Substring(int startIndex), string Substring(int startIndex, int length)
ToBoolean Method bool IConvertible.ToBoolean(System.IFormatProvider provider)
ToByte Method byte IConvertible.ToByte(System.IFormatProvider provider)
ToChar Method char IConvertible.ToChar(System.IFormatProvider provider)
ToCharArray Method char[] ToCharArray(), char[] ToCharArray(int startIndex, int length)
ToDateTime Method datetime IConvertible.ToDateTime(System.IFormatProvider provider)
ToDecimal Method decimal IConvertible.ToDecimal(System.IFormatProvider provider)
ToDouble Method double IConvertible.ToDouble(System.IFormatProvider provider)
ToInt16 Method int16 IConvertible.ToInt16(System.IFormatProvider provider)
ToInt32 Method int IConvertible.ToInt32(System.IFormatProvider provider)
ToInt64 Method long IConvertible.ToInt64(System.IFormatProvider provider)
ToLower Method string ToLower(), string ToLower(cultureinfo culture)
ToLowerInvariant Method string ToLowerInvariant()
ToSByte Method sbyte IConvertible.ToSByte(System.IFormatProvider provider)
ToSingle Method float IConvertible.ToSingle(System.IFormatProvider provider)
ToString Method string ToString(), string ToString(System.IFormatProvider provider), string I…
ToType Method System.Object IConvertible.ToType(type conversionType, System.IFormatProvider…
ToUInt16 Method uint16 IConvertible.ToUInt16(System.IFormatProvider provider)
ToUInt32 Method uint32 IConvertible.ToUInt32(System.IFormatProvider provider)
ToUInt64 Method uint64 IConvertible.ToUInt64(System.IFormatProvider provider)
ToUpper Method string ToUpper(), string ToUpper(cultureinfo culture)
ToUpperInvariant Method string ToUpperInvariant()
Trim Method string Trim(Params char[] trimChars), string Trim()
TrimEnd Method string TrimEnd(Params char[] trimChars)
TrimStart Method string TrimStart(Params char[] trimChars)
Chars ParameterizedProperty char Chars(int index) {get;}
Length Property int Length {get;}
I see that there are also some static members that have been added:
PS d:> $a | gm -Static
TypeName: System.String
Name MemberType Definition
—- ———- ———-
Compare Method static int Compare(string strA, string strB), static int Compare(string strA, string s…
CompareOrdinal Method static int CompareOrdinal(string strA, string strB), static int CompareOrdinal(string …
Concat Method static string Concat(System.Object arg0), static string Concat(System.Object arg0, Sys…
Copy Method static string Copy(string str)
Equals Method static bool Equals(string a, string b), static bool Equals(string a, string b, System….
Format Method static string Format(string format, System.Object arg0), static string Format(string f…
Intern Method static string Intern(string str)
IsInterned Method static string IsInterned(string str)
IsNullOrEmpty Method static bool IsNullOrEmpty(string value)
IsNullOrWhiteSpace Method static bool IsNullOrWhiteSpace(string value)
Join Method static string Join(string separator, Params string[] value), static string Join(string…
new Method string new(System.Char*, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b7…
ReferenceEquals Method static bool ReferenceEquals(System.Object objA, System.Object objB)
Empty Property static string Empty {get;}
The first thing I want to do is to break the string into an array of characters—a character array. Luckily, there is a string method that does just that. I will store the character array in a new variable, $b:
PS d:> $b = $a.ToCharArray()
PS d:> $b
a
b
c
d
e
So, now I want to reverse the character array. To do this, I use the static reverse method from the [array] object:
PS d:> [array]::Reverse($b)
PS d:> $b
e
d
c
b
a
Note The cool thing here is that the array reverses order. I do not need to save the output in a new variable.
$b now has a reversed array.
Now I want to regroup the elements of the array back into a string, and store that back into a variable:
PS d:> $c = -join($b)
PS d:> $c
Edcba
And my string is back to a string again:
PS d:> $c.GetType()
IsPublic IsSerial Name BaseType
——– ——– —- ——–
True True String System.Object
SS, that is all there is to using Windows PowerShell to reverse strings. Join me tomorrow when I will talk about more cools stuff.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy
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.
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 '' } } }
- Remove From My Forums
-
Question
-
I have a problem with the lower part
Pieces move around in a string
Replacement within a string, I know$qalias = $bname.replace(» «,»»)
$qalias = $qalias -replace («/»,».»)
$qalias = $qalias -replace («&»,»en»)
$qalias = $qalias -replace («-«,»»)But how do I turn this string into the desired reverse format
The names between the dots are variableOld
nw
rest.bgfs.fdmendsm.test.wkt.unit => unit.wkt.test.fdmendsm.bgfs.restbut it can also be;
Old nw
rest.bgfs.fdmendsm => fdmendsm.bgfs.rest
Answers
-
Thx for the answers
$a = «rest.bgfs.fdmendsm.test.wkt.unit»
$b = $a.split(«.»)
[array]::reverse($b)
$b = $b -join «.»unit.wkt.test.fdmendsm.bgfs.rest
This is the one can use
-
Marked as answer by
Wednesday, June 22, 2011 7:33 PM
-
Marked as answer by
My poor attempt to answer this question, as Abraham pointed out in his comment, you need to create an instance of the class:
class ReverseClass {
[string]$Stringy
ReverseClass([string]$String){
$this.Stringy = $String
}
[string]Reverse(){
return -join $this.Stringy[-1..-$this.Length()]
}
[int]Length(){
return $this.Stringy.Length
}
}
$z = [ReverseClass]'Hello World!'
$z.Reverse() # => !dlroW olleH
Again, I insist, a class is an overkill for what you need to do:
function Reverse-String([string]$String){
-join $String[-1..-$String.Length]
}
Reverse-String 'Hello world!' # => !dlrow olleH
If this class was stored on a file like C:usersusermy documentsscript.ps1
and you wanted to load the class or function to your current session you would need to dot source it (simply add a dot before the path). This will load all everything, classes, functions, variables, etc to your current scope.
For example:
- If your current directory is not where the script is stored:
. "C:usersusermy documentsscript.ps1"
- If you changed directory to
my documents
in this case:
. .script.ps1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# =========================================================================== | |
# Created on: 5/28/2018 @ 19:17 | |
# Created by: Alcha | |
# Organization: HassleFree Solutions, LLC | |
# Filename: Reverse-String.ps1 | |
# =========================================================================== | |
<# | |
.SYNOPSIS | |
A simple script for reversing a String. | |
.DESCRIPTION | |
A simple script for reversing a String in PowerShell in order to show some | |
basics of how to use the language. | |
.PARAMETER Input | |
The string to reverse. | |
.EXAMPLE | |
.Reverse-String.ps1 -Input ‘Hello, World’ | |
.NOTES | |
This is for the sample-programs repo available here on GitHub: | |
https://github.com/jrg94/sample-programs | |
#> | |
param | |
( | |
[Parameter(Mandatory = $true, | |
Position = 0)] | |
[ValidateNotNullOrEmpty()] | |
[string]$Args | |
) | |
$InputArray = $Args.ToCharArray() | |
[System.Array]::Reverse($InputArray) | |
$ReversedString = -join($InputArray) | |
Write-Host $ReversedString |
Exactly a month in of working from home and social distancing, last night I was playing around with some scripts and at some point I needed to read the last index or an array without knowing its length. Easy enough, regardless the array length, the last index is always -1:
PS C:> @(1,2,3,4,5,6,7,8)[-1] 8
This reminded me of a conversation I had some time ago with a colleague, he was trying to convince me of much much Python is better than Powershell (and I stoically resisted and counter-punched 😉). One of the many arguments he used to convince me was to show how easy it is in Python to revert a string:
>>> "Hello World"[::-1] 'dlroW olleH'
True, that looks easy and elegant but the Powershell solution is not that bad, is it?
PS C: > "Hello World"[-1..-20] -join '' dlroW olleH
A string is an array of characters, so I’m using the square brackets to read a sequence of characters from the original string. The trick here is that my starting point is index -1 (the last character of the string) and I’m moving backwards towards the first character; here I’m just using a negative index greater than the string length and powershell happily complies. I also need to join the output (with an empty string). If you want to be exact with the string length you could use something like:
PS C:> $string = 'Hello World' PS C:> $string[-1..-$string.Length] -join '' dlroW olleH
To follow by faith alone is to follow blindly – Benjamin Franklin
New role, spring cleaning and new modules
String is an object with sequence of characters. In PowerShell, strings are represented inside double quotes (“”) or single quotes (”).
The characters in a string objects are accessible by their respective index.
$var1 = "Good Morning Everyone"
# To print the first character
$var1[0]
# To print the last character
$var1[-1]
#or
$var1[$var1.Length-1]
To print the string as sequence of characters
$var1[0..$var1.length]
As the string is a character array, we can reverse the string by –
1. Accessing the string index from last to first and joining the characters
$var1 = "Good Morning Everyone"
$var1[$var1.Length..0] -join ""
# OR
$var1[-1..-$var1.Length ] -join ""
2. Using reverse method in arrays
$var1 = "Good Morning Everyone"
# Converting the string to character array
$temp = $var1.ToCharArray()
[array]::Reverse($temp)
# Joining the reversed array to string
$temp -join ""
If you know of other ways to reverse the string in PowerShell, comment below with the code !!!
Watch out for the next post about reversing string using Python.
Thank you for reading the article.
Пытаюсь вызвать этот класс, чтобы перевернуть строку в PowerShell, но не могу понять, как его вызвать … очень простой вопрос, но не знаю, как это сделать
class Reverse{
[string]$Stringy
[string]Reversi(){
return $(this.Stringy[-1..-$Stringy.length] -join "")
}
}
Тогда я не знаю, как назвать этот класс. Сама по себе инструкция return выполняет свою работу, но мне нужно вызвать класс, пожалуйста, помогите, никаких подсказок просто укажите на код, онлайн-справки нет.
4 ответа
Лучший ответ
Вы уверены, что вам нужен класс с методом экземпляра?
Если вместо этого вы измените метод на static
, вы можете передать любое строковое значение в качестве параметра метода и получить результат без необходимости создания экземпляра класса:
class ReverseClass {
static [string] Reverse([string]$string){
return -join $string[-1..-$string.Length]
}
}
Теперь вы можете вызвать его с помощью статического оператора-члена ::
:
PS ~> [ReverseClass]::Reverse("hello")
olleh
3
Mathias R. Jessen
12 Авг 2021 в 16:56
Моя неудачная попытка ответить на этот вопрос , как указал Абрахам в его комментарии, вам нужно создать экземпляр класса:
class ReverseClass {
[string]$Stringy
ReverseClass([string]$String){
$this.Stringy = $String
}
[string]Reverse(){
return -join $this.Stringy[-1..-$this.Length()]
}
[int]Length(){
return $this.Stringy.Length
}
}
$z = [ReverseClass]'Hello World!'
$z.Reverse() # => !dlroW olleH
Опять же, я настаиваю, класс — это излишек для того, что вам нужно сделать:
function Reverse-String([string]$String){
-join $String[-1..-$String.Length]
}
Reverse-String 'Hello world!' # => !dlrow olleH
Если этот класс был сохранен в таком файле, как C:usersusermy documentsscript.ps1
, и вы хотите загрузить класс или функцию в текущий сеанс, вам потребуется точечный источник it ( просто добавьте точка перед контуром ). Это загрузит все, классы, функции, переменные и т. Д. В вашу текущую область видимости.
Например:
- Если ваш текущий каталог находится не в том месте, где хранится скрипт:
. "C:usersusermy documentsscript.ps1"
- Если вы изменили каталог на
my documents
в этом случае:
. .script.ps1
4
Santiago Squarzon
12 Авг 2021 в 15:36
Продолжая мой комментарий.
Этот…
class Reverse{
[string]$Stringy
[string]Reversi(){
return $(this.Stringy[-1..-$Stringy.length] -join "")
}
}
… не является функцией PowerShell. Вот как вы объявляете функцию в PowerShell.
<#
.Synopsis
Short description
.DESCRIPTION
Long description
.EXAMPLE
Example of how to use this
.EXAMPLE
Another example of how to use this
#>
function Verb-Noun
{
[CmdletBinding()]
[Alias()]
[OutputType([int])]
Param
(
[string]$Param1,
[int]$Param2
)
}
# calling the function
Verb-Noun -Param1 '' -Param2 ''
Для строк нет причин явно приводить их как строки. Все, что заключено в кавычки (одинарные или двойные), автоматически рассматривается как строка.
Все это задокументировано в файлах справки PowerShell …
Get-Help -Name About_functions
… и MS Docs.
Хотя вы можете делать классы в PowerShell v5 и выше. Как описано в файлах справки Powershell …
Get-Help -Name About_classes
… и MS Docs.
0
postanote
12 Авг 2021 в 06:13
class Reverse{
[string]$Stringy
[string]Reversi(){
return $this.Stringy[-1..-$this.Stringy.length] -join ""
}
}
PS C:> $ reverse = New-Object Reverse -Property @ {Stringy = «Hello World»}
PS C:> $ reverse.Reversi ()
DlroW olleH
0
Gyula Kokas
12 Авг 2021 в 14:51
I sort of brushed over it on my last post but this is how you reverse a string.
function get-reversestring {
[CmdletBinding()]
param (
[string]$teststring
)
$ca = $teststring.ToCharArray()
[array]::Reverse($ca)
-join $ca
}
Take the input string and turn it into an array of chars. Use the reverse static method of the array class to reverse the array. Other useful array methods can be found in the documentation – https://docs.microsoft.com/en-us/dotnet/api/system.array?redirectedfrom=MSDN&view=netframework-4.7.2
-Join is used to stitch the reversed char array back into a string.
This entry was posted in Powershell. Bookmark the permalink.