5

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?

SystemNoob
  • 55
  • 5
  • You can use a regex like this `(?<=\d|\))[- ](?=\d)` https://regex101.com/r/4YR8ft/1 Actually.. it looks like you want to remove the parens too, so a little more work is needed. But the point is you can use lookahead/lookbehinds. – mpen Dec 06 '20 at 21:03
  • The regex above will only match `-` and `space`, not the parentheses. If that doesn't work for you, you can try this: `(?<=\d)[()\s-]|[()\s-](?=\d)` – Charlie Armstrong Dec 06 '20 at 21:05

2 Answers2

3

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.
Wiktor Stribiżew
  • 561,645
  • 34
  • 376
  • 476
-1

Note: This answer verifiably works and I believe it to be helpful. If you see a problem with it, do tell us.

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 last-name 345-678-9101'    -replace '(?<=[\d ])[()-]+ *'

This yields:

firstname lastname 1234567890
firstname lastname 2345678910
firstname last-name 3456789101
  • -replace (?<=[\d ])[()-] ? effectively removes all instances of (, ), and - (specified as a character set, [...]; to be safe, one or more (+) of them, to cover typos), along with optional (*) spaces right after - if preceded by ((?<=...)) either a digit (\d) or a space.

  • Note that not specifying a replacement operand to the -replace operator replaces the match with the empty string and therefore effectively removes the match.

The net effect is that all digits end up directly concatenated.

Note that the assumption is that (, ) and - only occur as part of the numeric (phone-number) parts of the file names, as in the sample input; a - as part of a last name is handled properly, however.

mklement0
  • 312,089
  • 56
  • 508
  • 622