如何使用Powershell检测CamelCase

3
我希望将形如ArtistTitle的歌曲名称拆分为Artist - Title
在PowerShell中,是否有一种检测驼峰式边界并执行替换的方法?这只应影响第一个边界,忽略其余的。
2个回答

8
您可以使用区分大小写的正则表达式,在任何大写字符前拆分字符串,删除空元素,然后使用短横线连接剩余部分:
PS> 'ArtistTitle' -csplit '(?=[A-Z])' -ne '' -join '-'
Artist-Title

如果只需分割第一个单词,请使用Split运算符的第二个参数(Max-substrings)指定返回的子字符串的最大数量。有关更多信息,请参见about_Split帮助主题:

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

更新:我能够通过使用一种正则表达式模式使命令更短,这种模式不会在大写字母是第一个字符(在字符串开头)时将其拆分,因此不会创建空项:

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

这非常简洁。你如何确保它仅在第一次出现时起作用?例如:'ArtistTitleAlbum' - KalenGi
修改了我的答案,请试一下。 - Shay Levy
在这样的正则表达式中,最好使用\p{Lu}来表示大写字母(\p{Ll}表示小写字母)。这种方式也适用于其他文化。 - Roman Kuzmin

0

我最终想到了一个迂回的方法来实现它。 代码检索文件名,搜索艺术家和标题之间的边界,并使用连字符将文件重命名为艺术家和标题之间。

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) }

更新:

结合Shay Levy的答案,最终命令更加简短:

ls  | foreach -Process { Rename-Item $_ -NewName ($_.Name -csplit '(?<!^)(?=[A-Z])',2 -join ' - ')}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接