SystemNoob
SystemNoob

Reputation: 55

How to remove whitespace between numbers only?

I have a bunch of directories named differently like this:

firstname lastname (123) 456 7890
firstname lastname (234) 567-8910
firstname lastname 345-678-9101

I'm trying to rename each directory to keep the name with a space but have no spaces between the numbers like this:

firstname lastname 1234567890
firstname lastname 2345678910
firstname lastname 3456789101

This is what I have going right now:

$destination = "D:\test"

Get-ChildItem -Path $destination -Recurse -Directory |
Rename-Item -NewName { $_.name -replace '[()\s-]',''} -Verbose

##output##
firstnamelastname1234567890
firstnamelastname2345678910
firstnamelastname3456789101

This kind of works but doesn't leave a space between the firstname lastname and phone number. I've been trying other regex patterns but can't find a solution to target numbers. Is there a way to target the whitespace between only numbers?

Upvotes: 5

Views: 1190

Answers (2)

mklement0
mklement0

Reputation: 439193

To complement Wiktor Stribiżew's helpful answer with a solution that is perhaps easier to conceptualize:

@(
  'firstname lastname (123) 456-7890', 
  'firstname lastname (234) 567-8910',
  'firstname lastname 345-678-9101'
) | ForEach-Object {
  # Split into the first and second space-separated token, 
  # and whatever tokens remain.
  $first, $second, $rest = $_ -split ' ', 3
  # Re-join the tokens with spaces, removing all non-digit chars.
  # from  whatever remained, and output the result.
  $first, $second, ($rest -replace '\D') -join ' '
}

This yields the following, as intended:

firstname lastname 1234567890
firstname lastname 2345678910
firstname lastname 3456789101
  • $first, $second, $rest = $_ -split ' ', 3 uses -split, the string-splitting operator, to split each input string into at most 3 space-separated tokens; that is, whatever follows the second space - even if it contains spaces - becomes the third - and by definition last - array element.

  • $rest -replace '\D' uses -replace, the regular-expression-based string replacement operator, to remove all non-digit (\D) characters from whatever part of the string that follows the second space-separated token ($rest).

  • -join, the string-joining operator, is used to re-join the resulting tokens with spaces, and the resulting string is output to the pipeline.

Upvotes: 0

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 627087

You can use

$_.name -replace '[^\w\s]*(\d+)\W*(?=[\d\W]*$)', '$1'

See the regex demo

Details

  • [^\w\s]* - any zero or more chars other than word and whitespace chars
  • (\d+) - Capturing group 1 ($1 refers to this value from the replacement pattern): one or more digits
  • \W* - any zero or more non-word chars...
  • (?=[\d\W]*$) - that are immediately followed with zero or more non-word or digit chars up to the end of string.

Upvotes: 4

Related Questions