Best way to replace characters in file names

I had to rename a bunch of files in a directory that included sub folders to remove any of these characters ‘,()&.’ and replace any spaces with a ‘_’. The below ran fine but I’m still learning and wondering if there was a better way of doing this.

$filelist = get-childitem -Path '\\Server\Share\Sub Folder' -Recurse -File
$filelist | % {Rename-Item -Path $_.fullname -NewName ($_.BaseName.replace('(','').replace(')','').replace(',','').replace('','_').replace('&','').replace('.','') + $_.extension)} 

The only issue with this is if a file name has more than one space together or already has a underscore and space next to it the name could contain multiple underscore characters in a row (File_ Name.file would rename to File__Name.file). I was hoping to figure out a regex solution to prevent multiple underscores together but just came up with this logic. Than you in advance for your thoughts!

$strings = 'test 1', 'test  2', 'test   3', 'test_    4', 'test _ _ _ _ _ 5'
foreach($string in $strings){
  $string = $string.replace(' ','_')
  while ($string -like '*__*'){
    $string = $string.Replace('__','_')

If it does the job … :wink:
But to make your code a little more sleak or sophisticated you could use another regex pattern like this:

‘A strange (file) name, like,.this & that,.’ -replace ‘(\s|(|)|,|.|&|)+‘,’

Amazing. Thank you! I did not know how to format the regex so I just did a bunch of replace() methods. I modified your regex, and test string, to get the exact result I needed.

'_  ____A strange (file) name, like,.this & that,._' -replace '(\(|\)|,|\.|&)+','' -replace '(_|\s)+','_'

If I got it right this could be even better … :wink:

‘_  A strange (file) name, like,.this & that,.’ -replace ‘((|)|,|.|&)+’,‘’ -replace '(|\s)+‘,’’ -replace '^|_$’,‘’

Here’s another option.

('_  ____A strange (file) name, like,.this & that,._' -replace '[_(),.&]+','').trim() -replace '\s+','_'