Conan1989
Conan1989

Reputation: 328

How to find string that occurs between 3rd and 4th instances of a character

What I think I'm needing is an expression to exclude anything outside of the 3rd and 4th instances of a character, backlashes in this case. Does that sound right?

The problem I'm trying to solve is how to get the ShareName from a given UNC path in PowerShell.

Find: "Share01" in example source string:

\\FQDN\Share01\Directories\...\...\...\...

PowerShell's Split-Path is proving to be a bit limitied in this regard, and RegEx is ...hard!

Upvotes: 1

Views: 635

Answers (4)

briantist
briantist

Reputation: 47832

Hm I'm really late to this party, but I will suggest an alternative: Use the [Uri] type:

$unc = '\\FQDN\Share01\Directories\...\...\...\...'
$upath = [Uri]$unc

Testing if the path really is a UNC path:

$upath.IsUnc

Getting the Share

$upath.Segments[1]            # Returns Share01/
$upath.Segments[1].Trim('/')  # Trims the trailing /

Or a one liner with no escaping or trimming:

[System.IO.Path]::GetPathRoot($unc).Split('\')[-1]

Upvotes: 9

Ansgar Wiechers
Ansgar Wiechers

Reputation: 200373

In simple scenarios I'd use an approach similar to the one suggested by @Avshalom, but with the String.Split() method instead of the -split operator to avoid regular expressions.

$unc = '\\FQDN\Share01\Directories\...\...\...\...'

$sharename = $unc.Split('\')[3]

If you want to be on the safe side you should canonicalize the path separators first, since PowerShell accepts both / and \ as separators in a path:

$sharename = $unc.Replace('/', '\').Split('\')[3]

If you want to play it really safe there probably isn't a way around regular expressions, though, because there are a number of things to take care of:

  • Ensure the path is actually a UNC path (i.e. starts with a double slash/backslash and has at least a server and share component).
  • Handle both \ and /.
  • Handle consecutive path separators (.//some\\\folder/\path is a valid pathspec in PowerShell).

To handle all of this you could do the following:

$unc = '\\FQDN\Share01\Directories\...\...\...\...'
$re  = '^[\\/]{2}[^\\/]+[\\/]+([^\\/]+)'

if ($unc -match $re) {
  $sharename = $matches[1]
} else {
  "Not a valid UNC path: $unc"
}

Regular expression breakdown:

  • ^[\\/]{2} matches two consecutive slashes or backslashes at the beginning of a string.
  • [^\\/]+ matches a sequence of one or more characters that are neither slash nor backslash (i.e. a path component).
  • [\\/]+ matches consecutive path separators.
  • (...) group a submatch (in this case the share name) so that it can be back-referenced, e.g. via the automatic variable $matches.

Upvotes: 8

Esperento57
Esperento57

Reputation: 17472

Modifiy this code for foud your search:

 $value="\\FQDN\Share01\Directories\...\...\...\..."
 $valuetosearch="Share01"
 $listresult=$value -split "\\"
 $counter = 0
 $listresult | select @{Name="Value";Expression={$_}}, @{Name="Rang";Expression={$global:counter; $global:counter++}} | where { $_.Rang -eq 3 -and $_.Value -eq $valuetosearch} 

Upvotes: 0

Avshalom
Avshalom

Reputation: 8889

Another option:

('\\FQDN\Share01\Directories\...\...\...\...' -split '\\' | ? {$_} )[1]

Upvotes: 4

Related Questions