Substring in PowerShell to reduce string length

Is it possible in PowerShell to truncate a string (using SubString() ?) SubString() given maximum number of characters, even if the original string is already shorter ?

For instance:

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

Truncation works on hello and good morning , but I get an error for hi .

I would like the following result:

 hell good hi 
+7
source share
4 answers

You need to evaluate the current element and get its length. If the length is less than 4, use it in the subscript function.

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

Or you can simply do this using PowerShell, an alternative to the ternary operator:

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

Although all other answers are “correct,” their effectiveness ranges from suboptimal to potentially terrible. The following is not a critique of the other answers, but is intended as an instructive comparison of their basic operation. In the end, scripting is more likely to be quick than quick.

With the aim of:

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

    Essentially, this is the same as my suggestion, except that instead of just returning $ str when it is too short, we call a substring and say we need to return the whole string. Therefore, not optimal. He still does if..then..else, but only inside Min, vis.

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

    Using regular expression matching to capture the first four characters and then replace them with the entire string means that the entire (possibly very long) string must be scanned by a matching mechanism of unknown complexity / efficiency.

    While a person can see that “. +” Just matches the rest of the line, the matching mechanism could create a large list of return options, as the template is not attached (no ^ at the beginning). (Not described) The smart bit here is that if a string is less than five characters (four times . Followed by one or more . ), Then the whole match fails and the substitute returns $ ul unchanged.

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

    Deliberately throwing exceptions instead of programmatically checking boundaries is an interesting solution, but who knows what happens when an exception pops up from the try block to the catch. There is probably not much in this simple case, but this will not be the recommended general practice, except in situations where there are many possible sources of errors (which makes it difficult to check all of them), but only a few answers.

Interestingly, the answer to a similar question elsewhere using -join and slicing arrays (which do not cause errors in the index out of range, just ignore the missing elements):

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

(or easier)

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

may be the most efficient (with appropriate optimization), given the strong similarities between storing string and char[] . Optimization would be required, since by default $ str [0..3] is an object [], each element is a single character and therefore has little resemblance to a string (in memory). Providing PowerShell with a little hint can be helpful,

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

However, maybe just saying that you really want to

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

thereby referring directly

 new String(char[]) 

best.

+8
source

You can block the exception:

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

You can also use -replace

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

Source: https://habr.com/ru/post/1211085/


All Articles