Domanda

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.

È stato utile?

Soluzione

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

Altri suggerimenti

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 ' - ')}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top