简体   繁体   中英

How to get a specific part of a string in Powershell

I'm struggeling to find an elegant way to split strings to a specific part. I have strings in such formats:

some text of any length (need)
some text of any length (need-notneed)
some text of any length (notneed) (need)
some text of any length (notneed) (need-notneed)

All I need is the part with the word need .

need can be of 3 to 5 characters long. These are things I can rely on:

  • Directly before need there's always a (
  • Directly after need there's always either a ) or a - (any text after and including - should be cut off as well)

I hope I have described it well... Sorry in case my English is not the best Greetings from Vienna

One option is to use switch -regex . We can use the regex pattern below to match the text you need.

Pattern - (?<=\\()\\S{3,5}(?=[-\\)])

  • Positive Lookbehind (?<=\\() (Assert that the Regex below matches)
    • \\( matches the character (
  • \\S matches any non-whitespace character (equivalent to [^\\r\\n\\t\\f\\v ])
  • {3,5} matches the previous token between 3 and 5 times, as many times as possible, giving back as needed (greedy)
  • Positive Lookahead (?=[-\\)]) (Assert that the Regex below matches)
    • [-\\)] will match either a - or )

Code

# some data to work with
$text = @'
some text of any length (need)
some text of any length (need-notneed)
some text of any length (notneed) (need)
some text of any length (notneed) (need-notneed)
some text of any length (RTX)
some text of any length (EOWD-notneed)
some text of any length (notneed) (12345)
some text of any length (notneed) (D.D03-notneed)
some text without any match
'@ -split '\r?\n'

# regex pattern that matches you requirement
$pattern = '(?<=\()\S{3,5}(?=[-\)])'

$results = switch -Regex ($text) {
    $pattern {
        [PSCustomObject]@{
            String = $_
            Match  = $Matches[0]
        }
    }
    Default { }
}
PS > $results

String                                            Match
------                                            -----
some text of any length (need)                    need
some text of any length (need-notneed)            need
some text of any length (notneed) (need)          need
some text of any length (notneed) (need-notneed)  need
some text of any length (RTX)                     RTX
some text of any length (EOWD-notneed)            EOWD
some text of any length (notneed) (12345)         12345
some text of any length (notneed) (D.D03-notneed) D.D03

PS > $results.Match

need
need
need
need
RTX
EOWD
12345
D.D03

That's the perfect pattern! Thanks Daniel! I will probably need hours to understand this regex ;-) But it works great:

$text = @'
some text of any length (need)
some text of any length (need-notneed)
some text of any length (notneed) (need)
some text of any length (notneed) (need-notneed)
some text of any length (RTX)
some text of any length (EOWD-notneed)
some text of any length (notneed) (12345)
some text of any length (notneed) (D.D03-notneed)
some text without any match
some text of any length (notn) (need)
'@ -split '\r?\n'

# regex pattern that matches your requirement
$pattern = '(?:.*)(?<=\()(\S{3,5})(?=[-\)])'

$results = switch -Regex ($text) {
    $pattern {
        [PSCustomObject]@{
            String = $_
            Match  = $Matches[1]
        }
    }
    Default { }
}

Will result in those matches:

PS> $results                 
                                     
String                                            Match
------                                            -----
some text of any length (need)                    need 
some text of any length (need-notneed)            need 
some text of any length (notneed) (need)          need 
some text of any length (notneed) (need-notneed)  need 
some text of any length (RTX)                     RTX  
some text of any length (EOWD-notneed)            EOWD 
some text of any length (notneed) (12345)         12345
some text of any length (notneed) (D.D03-notneed) D.D03
some text of any length (notn) (need)             need

See especially the last match that matches now correctly! It also makes no difference if started with an array or a single string - both matches correctly.

Thanks again!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM