[英]Substring in PowerShell to truncate string length
是否有可能在 PowerShell 中將字符串截斷(使用SubString()
?)到給定的最大字符數,即使原始字符串已經更短了?
例如:
foreach ($str in "hello", "good morning", "hi") { $str.subString(0, 4) }
截斷適用於hello
和good morning
,但我收到hi
的錯誤。
我想要以下結果:
hell
good
hi
您需要評估當前項目並獲得它的長度。 如果長度小於 4,則在 substring 函數中使用它。
foreach ($str in "hello", "good morning", "hi") {
$str.subString(0, [System.Math]::Min(4, $str.Length))
}
或者你可以保持簡單,使用 PowerShell 替代三元運算符:
foreach ($str in "hello", "good morning", "hi") {
$(if ($str.length -gt 4) { $str.substring(0, 4) } else { $str })
}
雖然所有其他答案都是“正確的”,但它們的效率從次優到潛在的可怕。 以下內容不是對其他答案的批評,而是旨在對其基本操作進行有益的比較。 畢竟,腳本編寫更多的是讓它盡快運行而不是讓它快速運行。
為了:
foreach ($str in "hello", "good morning", "hi") { $str.subString(0, [System.Math]::Min(4, $str.Length)) }
這與我的產品基本相同,只是在 $str 太短時不只是返回,我們調用 substring 並告訴它返回整個字符串。 因此,次優。 它仍在執行 if..then..else 但就在 Min 內部,vis。
if (4 -lt $str.length) {4} else {$str.length}
foreach ($str in "hello", "good morning", "hi") { $str -replace '(.{4}).+','$1' }
使用正則表達式匹配獲取前四個字符,然后用它們替換整個字符串意味着整個(可能很長)字符串必須由未知復雜性/效率的匹配引擎掃描。
雖然人們可以看到 '.+' 只是為了匹配字符串的整個剩余部分,但匹配引擎可能會建立一個大的回溯替代列表,因為模式沒有錨定(開頭沒有 ^)。 此處(未描述)的巧妙之處在於,如果字符串少於五個字符(四次.
后跟一個或多個.
),則整個匹配失敗並替換返回 $str 不變。
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[])
是最好的。
您可以捕獲異常:
foreach ($str in "hello", "good morning", "hi") {
try {
$str.subString(0, 4)
}
catch [ArgumentOutOfRangeException] {
$str
}
}
更多正則表達式愛,使用lookbehind:
PS > 'hello','good morning','hi' -replace '(?<=(.{4})).+'
hell
good
hi
我和往常一樣遲到! 我已經使用 PadRight 字符串函數來解決這樣的問題。 與其他建議相比,我無法評論其相對效率:
foreach ($str in "hello", "good morning", "hi") { $str.PadRight(4, " ").SubString(0, 4) }
您也可以使用-replace
foreach ($str in "hello", "good morning", "hi") { $str -replace '(.{4}).+','$1' }
hell
good
hi
舊線程,但我遇到了同樣的問題,結果如下:-
$str.padright(4,"✓").substring(0,4).replace("✓","")
用你想要的任何流氓角色替換 ✓ 字符。 我使用了通過按鍵盤上的 ALT GR 和反引號鍵獲得的字符。
呃,我覺得很臟,但它是:
-join ("123123123".ToCharArray() | select -first 42)
輸出完整字符串: 123123123
-join ("123123123".ToCharArray() | select -first 3)
輸出前 3 個字符: 123
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.