2015-01-14 84 views
5

是否有可能在PowerShell中,以截斷字符串(使用SubString()?),字符的給定的最大數,甚至如果原始字符串已經是子串在PowerShell來截斷字符串長度

例如:

foreach ($str in "hello", "good morning", "hi") { $str.subString(0, 4) } 

截斷正在爲hellogood morning,但我得到一個錯誤的hi

我想以下結果:

hell 
good 
hi 
+0

如果你想添加字符,如果它更短,並刪除它們,如果它更長? – arco444

+0

如果更短,保持字符串不變,不需要添加字符。 –

回答

14

您需要評估當前項目,並得到了它的長度。如果長度小於4,則在子字符串函數中使用該長度。

foreach ($str in "hello", "good morning", "hi") { 
    $str.subString(0, [System.Math]::Min(4, $str.Length)) 
} 
1

您可以捕獲該異常:

foreach ($str in "hello", "good morning", "hi") { 
    try { 
    $str.subString(0, 4) 
    } 
    catch [ArgumentOutOfRangeException] { 
    $str 
    } 
} 
0

您還可以使用-replace

foreach ($str in "hello", "good morning", "hi") { $str -replace '(.{4}).+','$1' } 

hell 
good 
hi 
+1

您的輸出與要求的內容不符。 – Duncan

+0

@Duncan你的權利。固定 – mjolinor

5

或者你可以保持它的簡單,使用PowerShell的替代三元操作符:

foreach ($str in "hello", "good morning", "hi") { 
    $(if ($str.length -gt 4) { $str.substring(0, 4) } else { $str }) 
} 

儘管所有其他答案都是「正確的」,但它們的效率卻從次優到潛在可怕。以下不是對其他答案的批評,而是作爲對其基本操作的指導性比較。畢竟,腳本編寫更多的是讓它快速運行,而不是讓它快速運行。

爲了:

1.

foreach ($str in "hello", "good morning", "hi") { 
    $str.subString(0, [System.Math]::Min(4, $str.Length)) 
} 

這是基本相同,不同的是我,而不是僅僅提供返回時太短$海峽,我們所說的子串,並告訴它返回整個字符串。因此,次優。它仍然在做if .. then .. else,但在min,vis內。

if (4 -lt $str.length) {4} else {$str.length} 

2.

foreach ($str in "hello", "good morning", "hi") { $str -replace '(.{4}).+','$1' } 

使用正則表達式匹配來獲取第一4個字符,然後更換整個字符串與它們意味着整個(可能很長)字符串必須由匹配被掃描未知複雜性/效率的引擎。雖然一個人可以看到'。+'僅僅是匹配整個字符串的其餘部分,但匹配引擎可能會建立一個大量的回溯替代方案,因爲該模式沒有被錨定(開始時沒有^)。這裏沒有描述的聰明點是如果字符串小於5個字符(4次,後面跟1個或更多),那麼整個匹配失敗並且替換返回$ str不變。

3。

foreach ($str in "hello", "good morning", "hi") { 
    try { 
    $str.subString(0, 4) 
    } 
    catch [ArgumentOutOfRangeException] { 
    $str 
    } 
} 

故意拋出異常,而不是編程邊界檢查是一個有趣的解決方案,但誰知道是怎麼回事作爲異常從try塊到catch冒泡。在這種簡單的情況下可能並不多,但除了有很多可能的錯誤來源(使其檢查所有這些錯誤很麻煩),但只有少數幾個響應的情況之外,它不會被推薦爲一般慣例。

有趣的是,回答一個類似的問題在別處使用-join和陣列片(不引起對索引錯誤超出範圍,只是忽略缺少的元素)

$str[0..3] -join "" # infix 

(或更簡單)

-join $str[0..3]  # prefix 

考慮到string和char []存儲之間的強相似性,可能是最有效的(經過適當的優化)。優化將是必需的,因爲默認情況下,$ str [0..3]是一個對象[],每個元素都是單個字符,因此與字符串(在內存中)幾乎沒有相似之處。給予PowerShell的一個小提示可能是有用的,

-join [char[]]$str[0..3] 

然而,也許只是告訴它你真正想要的東西,

new-object string (,$str[0..3]) # need $str[0..3] to be a member of an array of constructor arguments 

從而直接調用

new String(char[]) 

是最好的。