【发布时间】:2015-09-27 12:04:53
【问题描述】:
场景
我正在使用第 3 方文件重命名软件,该软件用 Delphi 编写并支持 pascal 脚本:http://www.den4b.com/?x=products&product=renamer
该应用程序允许使用正则表达式来重命名文件。这意味着如果我需要对文件名执行的操作不能仅使用一个 RegEx 来完成,那么我可以同时使用各种表达式或帕斯卡脚本代码来容纳文件名,直到我可以根据需要正确格式化文件名问题或其他任何事情......
问题
我需要像下面这样格式化歌曲文件名,在这些文件名中,“...特征艺术家”部分位于字符串的右侧,我需要匹配它并将其定位在字符串的左边部分。
- Carbin 和 Sirmark - 对不起壮举。七人
- Kristjan Cash Cash - 带我回家壮举。 Bebe Rexha(撤销混音)
为了让这个简单易懂,我们可以想象 tokenize 像这样的文件名:
[0]ARTIST [1]DASH [2]TRACK [3]FEAT_ARTIST [4]POSSIBLE_ADDITIONAL_INFO_INSIDE:()[]{}
然后我需要用 RegEx 做的就是格式化文件名以按以下顺序定位 tokens:
[0]ARTIST [3]FEAT_ARTIST [1]DASH [2]TRACK [4]POSSIBLE_ADDITIONAL_INFO_INSIDE:()[]{}
我实际上是使用这个 RegEx 来做到这一点的:
\A([^-]?)\s-\s*(.?)\s([([])?((ft[. \s]|feat[.\s]|featuring[.\s])[^(){}[]]*)([)]])?(.+)?\Z
替换为:
$1 $4 - $2$7
问题从这里开始,因为[0]ARTIST 和[2]TRACK 标记可能包含破折号,例如这个文件名:
- Dj E-nergy C-21 - 我的超级英雄曲目!壮举 Dj 混蛋
那么,如果我错了,请纠正我,但我认为它不可能以任何方式解决这个问题,因为机器无法预测何时将一个令牌分开,什么是名字或什么不是' t,因为我不知道包含文件名的破折号的数量。
因此,与其寻找可能导致坏事的巧妙完美 文件名因为里面的破折号数量,我更喜欢找一个 文件名排除解决方案,通过限制表达式的破折号 应该在文件名中匹配。
问题
以我上面展示的 RegEx 为例来扩展/改进它,我如何排除包含[0]ARTIST 或带有破折号的[2]TRACK 标记的文件名?
...或者换句话说,当文件名包含超过 1 个破折号在“...特色艺术家强>”部分? (不是之后)
基本上,Regex 应该确定在[3]FEAT_ARTIST 之前是否多次找到[1]DASH,如果是,则排除该文件名(不要修改它)
我知道如何限制 Regex 组的出现,或多或少类似于 ([\-]){1} 以仅匹配 1 个破折号出现,但我不确定如何在我正在使用的表达式中实现它。
预期结果
只是一些随机的例子......
仅在 [3]FEAT_ARTIST 之前添加一个破折号,以便我们知道何时将 [0]ARTIST 与 [2]TRACK 标记分开。
- 来自:'Carbin & Sirmark - 抱歉的壮举。七人'
- 致:'Carbin & Sirmark Feat。 Sevener - 对不起'
只在[3]FEAT_ARTIST 之前添加一个破折号,这样我们就可以知道何时将[0]ARTIST 与[2]TRACK 标记分开。与[4]POSSIBLE_ADDITIONAL_INFO_INSIDE:()[]{}。
- 来自:'飞行设施 - 心脏病发作壮举。猫头鹰的眼睛(蛇臀混音)'
- 致:'飞行设施壮举。猫头鹰的眼睛 - 心脏病发作(Snakehips Remix)'
只在[3]FEAT_ARTIST 之前添加一个破折号,这样我们就可以知道何时将[0]ARTIST 与[2]TRACK 标记分开。 [4]POSSIBLE_ADDITIONAL_INFO_INSIDE:()[]{} 也包含破折号。
- 来自:'飞行设施 - 心脏病发作壮举。 Owl Eyes [Snake--hips Remix]'
- 致:'飞行设施壮举。猫头鹰的眼睛 - 心脏病发作 [Snake--hips Remix]'
[0]ARTIST 和 [2]TRACK 标记之间只有一个破折号,但文件名没有 [3]FEAT_ARTIST,所以我们不碰它。
- 来自:'Fedde Le Grand - 电影'
- 致:'Fedde Le Grand - 电影'
只在[0]ARTIST 和[2]TRACK 标记之间有一个破折号,但[3]FEAT_ARTIST 在[1]DASH 之前,所以我们不碰它。
- 来自:'Fedde Le Grand Feat。 Denny White - 电影'
- 致:'Fedde Le Grand Feat。 Denny White - 电影'
[0]ARTIST 有破折号,因此我们不知道何时将[0]ARTIST 和[2]TRACK 标记分开,因此正则表达式应排除它以不修改此文件名。
- 来自:'Artist-Name - Track Name feat someone'
- 致:'Artist-Name - Track Name feat someone'
[2]TRACK 有破折号,所以我们不知道何时将[0]ARTIST 和[2]TRACK 标记分开,因此正则表达式应排除它以不修改此文件名。
- 发件人:'艺术家姓名 - 曲目-名字的壮举'
- 致:“艺人姓名 - 曲目名称,壮举某人”
- 来自:'Dj E-nergy C-21 - 我的超级英雄曲目!壮举 Dj 混蛋'
- 致:'Dj E-nergy C-21 - 我的超级英雄曲目!壮举 Dj 混蛋'
[0]ARTIST 和 [2]TRACK 标记有破折号,[3]FEAT_ARTIST 也不存在,这里也没什么可做的。
- 来自:'Dj E-nergy C-21 - 我的超级英雄曲目!'
- 致:'Dj E-nergy C-21 - 我的超级英雄曲目!'
我希望这有助于理解我需要什么。
【问题讨论】:
-
只是一个想法,但字符串是否可以包含分隔字符串各个部分的不可打印字符(如
、 )?这些可以在打印到屏幕之前删除或由正则表达式解析器使用。 -
@AlainD 感谢您的评论,文件名不包含控制字符,最初在某些情况下我发现文件名包含特殊的 unicode 破折号或其他特殊符号,但我之前删除/转换了所有这些特殊字符使用这个问题的正则表达式。
-
什么是正则表达式风格?如果您不指定,那么得到不使用相同风格的答案也就不足为奇了。
标签: regex delphi pattern-matching filenames pascalscript