我需要将多个Url元素连接成一个字符串,因此我编写了通用的Join-Parts函数:
filter Skip-Null { $_|?{ $_ } }
function Join-Parts
{
param
(
$Parts = $null,
$Separator = ''
)
[String]$s = ''
$Parts | Skip-Null | ForEach-Object {
$v = $_.ToString()
if ($s -ne '')
{
if (-not ($s.EndsWith($Separator)))
{
if (-not ($v.StartsWith($Separator)))
{
$s += $Separator
}
$s += $v
}
elseif ($v.StartsWith($Separator))
{
$s += $v.SubString($Separator.Length)
}
}
else
{
$s = $v
}
}
$s
}
Join-Parts -Separator '/' -Parts 'http://mysite','sub/subsub','/one/two/three'
Join-Parts -Separator '/' -Parts 'http://mysite',$null,'one/two/three'
Join-Parts -Separator '/' -Parts 'http://mysite','','/one/two/three'
Join-Parts -Separator '/' -Parts 'http://mysite/','',$null,'/one/two/three'
Join-Parts 1,2,'',3,4
按预期返回:
http://mysite/sub/subsub/one/two/three
http://mysite/one/two/three
http://mysite/one/two/three
http://mysite/one/two/three
1234
我觉得这不是最聪明的方法。有关更好方法的任何想法吗?
更新
根据@sorens的回答,我将功能改为:
function Join-Parts
{
param
(
$Parts = $null,
$Separator = ''
)
($Parts | ? { $_ } | % { ([string]$_).trim($Separator) } | ? { $_ } ) -join $Separator
}
答案 0 :(得分:8)
在@mjolinor的答案的基础上,这个单线传递了你问题中的所有测试:
($parts | ? { $_ } | % { ([string]$_).trim('/') } | ? { $_ } ) -join '/'
如果你真的不关心最后一个测试用例(1,2,'',3,4)
并且可以假设所有输入都是字符串,你可以将其缩短为:
($parts | ? { $_ } | % { $_.trim('/') } | ? { $_ } ) -join '/'
请注意,我有两个 null / empty过滤器(? { $_ } )
:第一个从输入中删除空值或空字符串,这会使用空字符串{{1}来纠正您的测试用例}。第二个也是必要的,通过trim函数将输入简化捕获为空。
如果你真的想要对它很挑剔,你应该再添加一个修剪来消除只有空格的值,因为那些可能是不需要的:
('http:/fdfdfddf','','aa/bb')
使用最后一个这些测试用例输入也将返回($parts | ? { $_ } | % { $_.trim('/').trim() } | ? { $_ } ) -join '/'
:
http://mysite/one/two
答案 1 :(得分:5)
以下是使用UriBuilder类创建URL的示例:
$builder = New-Object System.UriBuilder
$builder.Host = "www.myhost.com"
$builder.Path = ('folder', 'subfolder', 'page.aspx' -join '/')
$builder.Port = 8443
$builder.Scheme = 'https'
$builder.ToString()
输出:
https://www.myhost.com:8443/folder/subfolder/page.aspx
更新 - 这是一个应该能够合并您的网址部分的小功能:
function Join-Parts {
param ([string[]] $Parts, [string] $Seperator = '')
$search = '(?<!:)' + [regex]::Escape($Seperator) + '+' #Replace multiples except in front of a colon for URLs.
$replace = $Seperator
($Parts | ? {$_ -and $_.Trim().Length}) -join $Seperator -replace $search, $replace
}
Join-Parts ('http://mysite','sub/subsub','/one/two/three') '/'
Join-Parts ('http://mysite',$null,'one/two/three') '/'
Join-Parts ('http://mysite','','/one/two/three') '/'
Join-Parts (1,2,'',3,4) ','
输出:
http://mysite/sub/subsub/one/two/three
http://mysite/one/two/three
http://mysite/one/two/three
1,2,3,4
答案 2 :(得分:5)
你可以这样做:
($parts | foreach {$_.trim('/'))} -join '/'
答案 3 :(得分:2)
Powershell有一个-join
运算符。如需帮助,请输入帮助about_join
答案 4 :(得分:2)
从Path.Combine for URLs?的最高答案中汲取灵感
function Combine-UriParts ($base, $path)
{
return [Uri]::new([Uri]::new($base), $path).ToString()
}
应该足够容易地扩展到多个部分