Question

I would like to split song names that are in the form ArtistTitle so that they end up as Artist - Title

Is there a way in Powershell to detect the CamelCase boundary and perform the replacement? This should only affect the first case boundary and ignore the rest.

Was it helpful?

Solution

You can use a case sensitive regular expression to split the string right before any upper case character, remove empty elements and then join what's left with a dash:

PS> 'ArtistTitle' -csplit '(?=[A-Z])' -ne '' -join '-'
Artist-Title

To split just the first word, use the second parameter of the Split operator (Max-substrings) to specifys the maximum number of substrings returned. See the about_Split help topic for more information:

PS> 'ArtistVeryLongAlbumTitle' -csplit '(?=[A-Z])',3  -ne '' -join '-'
Artist-VeryLongAlbumTitle

UPDATE: I was able to make the command shorter by using a regex pattern that doesn't split an uppercase char if it is the first one (at the beginning of the string) so an empty item is not created:

PS>  'ArtistVeryLongAlbumTitle' -csplit '(?<!^)(?=[A-Z])',2 -join '-'
Artist-VeryLongAlbumTitle

OTHER TIPS

I ended up crafting a roudabout way of doing it. The code retrieves the file names, searches for the ArtistTitle boundary and renames the file with a hyphen between the Artist and Title.

ls | foreach { $result = ($_.Name -cmatch '^(\w*?[a-z])([A-Z])'); $search = "$($matches[1])$($matches[2])"; $replace = "$($matches[1]) - $($matches[2])"; Rename-Item $_ -NewName ($_.Name -replace $search, $replace) }

UPDATE:

Incorporating Shay Levy's answer the resulting command is much shorter:

ls  | foreach -Process { Rename-Item $_ -NewName ($_.Name -csplit '(?<!^)(?=[A-Z])',2 -join ' - ')}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top