Write a powershell class to reverse a string word by word

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! Question 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

Hey, Scripting Guy! Answer 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 ""

image

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

image

Lastly, we need to bring everything back on one line.

image

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 ''

image

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'))

image

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 variable

    Old                                               
    nw
    rest.bgfs.fdmendsm.test.wkt.unit => unit.wkt.test.fdmendsm.bgfs.rest

    but 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

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

Show hidden 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.

Понравилась статья? Поделить с друзьями:
  • Write a sentence with the word accident
  • Write a sentence with the circled word перевод
  • Write a sentence with each spelling word
  • Write a sentence using word not
  • Write a sentence using the word where