簡體   English   中英

Substring in PowerShell 截斷字符串長度

[英]Substring in PowerShell to truncate string length

是否有可能在 PowerShell 中將字符串截斷(使用SubString() ?)到給定的最大字符數,即使原始字符串已經更短了?

例如:

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

截斷適用於hellogood 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 })
}

雖然所有其他答案都是“正確的”,但它們的效率從次優到潛在的可怕。 以下內容不是對其他答案的批評,而是旨在對其基本操作進行有益的比較。 畢竟,腳本編寫更多的是讓它盡快運行而不是讓它快速運行。

為了:

  1.  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}
  2.  foreach ($str in "hello", "good morning", "hi") { $str -replace '(.{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

鑒於stringchar[]的存儲之間的強烈相似性,可能是最有效的(經過適當的優化)。 需要優化,因為默認情況下,$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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM