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

4

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
  • 607,720
  • 39
  • 448
  • 563
-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 (*) following spaces - 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.

mklement0
  • 382,024
  • 64
  • 607
  • 775