Reputation: 55
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
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
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