2017-10-03 7 views
0

私はこれについて不満を抱くのが間違っている場合、私を許してください。しかし、これがPowerShellのようなスクリプト言語で何かをリモートで複雑にしようとするのが嫌な理由です。予測不可能な戦いは決して終わらない。これはPowerShellのTrimStartのバグですか?

だから、ここにある:

PS C:\WINDOWS\system32> $PSVersionTable.PSVersion 

Major Minor Build Revision 
----- ----- ----- -------- 
5  1  15063 632 

PS C:\WINDOWS\system32> $testpath = "\\a-server-unc\home\auser\Outlook Data\archive1 - Copy.pst" 

PS C:\WINDOWS\system32> $(Split-path -path $testpath -Parent) 
\\a-server-unc\home\auser\Outlook Data #Ok - Looks good 

PS C:\WINDOWS\system32> $(Split-path -path $testpath -Parent).TrimStart("\\a-server-unc") 
home\auser\Outlook Data # Where did my slash go? 

PS C:\WINDOWS\system32> $(Split-path -path $testpath -parent).TrimStart("\\a-server-unc\home") 
Outlook Data # Wait - What the... 

PS C:\WINDOWS\system32> $testpath 
\\a-server-unc\home\auser\Outlook Data\archive1 - Copy.pst # Yep - I'm not insane. Powershell is eating my characters. 

PS C:\WINDOWS\system32> $testpath = "\\a-server-unc\home\aloser\Outlook Data\archive1 - Copy.pst" #Let's try changing the string a little 

PS C:\WINDOWS\system32> $(Split-path -path $testpath -Parent).TrimStart("\\a-server-unc\home") 
loser\Outlook Data # I must be insane 

PS C:\WINDOWS\system32> $(Split-path -path $testpath -Parent).TrimStart("`\`\a-server-unc`\home") #Certainly escaping the slashes will fix this? 
loser\Outlook Data # Nope, more hours wasted on unpredictable behavior 

今明らかに存在ここではいくつかの奇妙な、「完全に正常な」動作ですが、私はPowerShellが私の文字列を食べて少し疲れています。

ここで魔法の薬は何ですか? (あなたが期待しているように見えるよう)TrimStart()を入力し、いない文字列として文字列を取ることに注意し、特にhttps://msdn.microsoft.com/en-us/library/system.string.trimstart.aspx

+0

「私はPowerShellのようなスクリプト言語でのリモートでの複雑な何かをしようとしている嫌い、なぜ*がしかし、これは、それは予測不可能で終わることのない戦いです*。。」 - ネットでString.TrimStart()がありましたPowerShellが存在する前の少なくとも3年(15年以上)。これはC#とVB.Net、Python、PHPでも同じです。 JavaScript、Java、Swift、Ruby、C++のstd :: stringには存在しません(いずれの形式でも)。私が今までに見つけた唯一の言語は、両方のバージョンの選択肢があるGoです。どの言語があなたから来ていますか?あなたはそれが異なると予測し、それを「予測不可能」と表現するように導きますか? – TessellatingHeckler

+0

とにかく、 '.Trim()'は文字列の両端からスペースを削除します。スペース、タブ、改行です。特定の文字を削除するように拡張することもできます。任意の種類の引用符文字、または文字列の両側から任意の種類の括弧/括弧を削除します。そのコンテキストでは、文字配列が意味を成し、.TrimStartと.TrimEndを制限する方が意味があります。もう一方の方法を一般化すると、一方の端から固定された文字列を取り除くことができる関数が、両端から固定された文字列を取り除くことができる関数になるようにするのは意味がありません。 – TessellatingHeckler

+0

'-replace"^\\\\ a-server-unc "'とすると、特殊文字がエスケープするか、 '[regex] :: Escape()' 'が必要な正規表現パターンにマッチするという警告が表示されます。デフォルトでは大文字と小文字を区別しません( '.Replace()'は大文字と小文字を区別します)。 – TessellatingHeckler

答えて

2

予想される動作です。文書1として

String.TrimStart法(CHAR())

は、現在の文字列オブジェクトの配列で指定された文字の組のすべての主要な発生を削除します。 - source

連続した文字列をトリミングするには、\出力は、サーバーのUNC \ Outlookデータ\

ホーム\ユーザーにつながる正規表現

"\a-server-unc\home\user\a-server-unc\Outlook Data\archive1" -replace "^\\a-server-unc\\",'' 

を使用して-replace使用することができますアーカイブ1

キー文字には、^を含めると、その開始がラインではなくどこかで(だからこその第二の出現私の置き換えとどまった。)あなたは正規表現を避けることを好む場合、あなたはこのような何か必要があるだろう

:2での違いは

function TrimStart([String]$InputObject,[String]$Value){ 
    if ($InputObject.StartsWith($Value)) { 
     return $InputObject.Substring($value.Length,$InputObject.Length - $value.Length) 
    } 
    else{ 
     return $InputObject 
    } 
} 

ここにありますですアクション。 $ ConceptString = 'これは完全なセンテンスである非常に長い文字列です!!!'

write-host $ConceptString.TrimStart('This is a very long string') -ForegroundColor Cyan 
#Output: ppens to be a complete sentence !!! 
Write-host $(TrimStart $ConceptString -Value 'This is a very long string') -ForegroundColor Green 
#output: that also happens to be a complete sentence !!! 
+0

PowerShellにこれを行う機能が組み込まれていることを期待していました。 '.Replace($ startstring、" ")は、文字列が文字列の先頭にしか存在しないと確信していたので、私は終わりました。しかし、あなたのソリューションはより正確で適切に機能します。ありがとう。 – Appleoddity

+0

上部の私の編集を参照してください。実際には、サポート正規表現を置き換えるので、行の先頭だけを対象とするpowershellビルトインの1ライナー置き換えを持つことができます。 –

1

ここTrimStart()マニュアルを参照してください

public string TrimStart(
    params char[] trimChars 
) 

をのでTrimStart()が削除されます文字列全体ではありません。

参照は、例えば、出力:

$testpath = "hhhhhhhhhhhhhhelloooooooo".TrimStart("h") 

それは出力:

をelloooooooo

溶液の代わりReplace()関数を使用することです。そうする

このような方法の1つ:$newPathため

$testpath = "\\a-server-unc\home\auser\Outlook Data\archive1 - Copy.pst" 
$basepath = "\\a-server-unc\" 
[regex]$pattern = [regex]::escape($basepath) 
# pattern is regex version of string you want to replace 
# .replace("string to replace", "replacing string", numberOfReplacements) 
# i.e. only replace the 1st instance 
$newPath = $pattern.replace($testpath, [string]::Empty, 1) 

出力:

ホーム\ AUSER \ Outlookデータ\のアーカイブ1 - Copy.pst

+0

ありがとう、私はちょうどそれを見て、それを読んでいた。他の文字列の先頭から確実に文字列を削除するには、適切な代替手段がありますか? – Appleoddity

+1

補遺として '.Replace()'を使用して期待される結果を得て、空の文字列で置き換えます。たとえば、次のようになります。 '.Replace( '\\ a-server-unc'、 [string] :: Empty)' – Persistent13

+0

これは問題ない解決策です。しかし、それは、先頭以外の別の場所でメインストリング内で発生する部分文字列を考慮していません。これは予期しない結果を招く可能性があります。しかし、ありがとう。 – Appleoddity

関連する問題