修复 RegEx 以正确捕获括号内的文本
Posted
技术标签:
【中文标题】修复 RegEx 以正确捕获括号内的文本【英文标题】:Fix RegEx to properly capture text inside parenthesis 【发布时间】:2016-06-03 21:33:29 【问题描述】:场景
前段时间我问了一个在特定条件下格式化音乐文件名的问题:
RegEx pattern to limit dashes in these circumstances但是,我发现接受的答案是错误的为时已晚,因为它可以捕获任何以“F”开头的单词。但这不是问题/问题,我只是通过恢复ft|feat|featuring
OR 组来解决它。
所以最后从上面链接的问题中,我最终使用了这个表达式:
pattern := '^(.+)\s+-\s+(.+?)\s+(ft|feat|featuring)[\.\s]*([^([\])]+)(.+)?$'
replace := '$1 Feat. $4 - $2$5'
现在,有这些文件名要测试:
-
黑海岸 - Trndsttr
黑海岸 - Trndsttr(羽毛)
Black Coast - Trndsttr (Lucian Remix)
Black Coast - Trndsttr (Feather) (Lucian Remix)
黑海岸 - Trndsttr 壮举。 M. Maggie
黑海岸 - Trndsttr (Feat. M. Maggie)
黑海岸 - Trndsttr 壮举。 M. Maggie(卢西恩混音)
Black Coast - Trndsttr (Feat. M. Maggie) (Lucian Remix)
Black Coast - Trndsttr (Lucian Remix) Feat。 M. Maggie
Black Coast - Trndsttr (Lucian Remix) (Feat. M. Maggie)
Black Coast - Trndsttr (Feather) (Lucian Remix) Feat. M. Maggie
Black Coast - Trndsttr (Feather) (Lucian Remix) (Feat. M. Maggie)
黑海岸 - Trndsttr(羽毛)壮举。 M. Maggie(卢西恩混音)
Black Coast - Trndsttr (Feather) (Feat. M. Maggie) (Lucian Remix)
Black Coast - Trndsttr (Feather) (Feat. M. Maggie) Lucian Remix
黑海岸 - Trndsttr(羽毛)壮举。 M. Maggie Lucian 混音
预期结果如下:
(从 1 到 4 没有变化,16 是假设的误报,本质上与 5、9 和 11 相同。)
-
黑海岸 - Trndsttr
黑海岸 - Trndsttr(羽毛)
Black Coast - Trndsttr (Lucian Remix)
Black Coast - Trndsttr (Feather) (Lucian Remix)
黑海岸壮举。 M. Maggie - Trndsttr
黑海岸壮举。 M. Maggie - Trndsttr
黑海岸壮举。 M. Maggie - Trndsttr (Lucian Remix)
黑海岸壮举。 M. Maggie - Trndsttr (Lucian Remix)
黑海岸壮举。 M. Maggie - Trndsttr (Lucian Remix)
黑海岸壮举。 M. Maggie - Trndsttr (Lucian Remix)
黑海岸壮举。 M. Maggie - Trndsttr (Feather) (Lucian Remix)
黑海岸壮举。 M. Maggie - Trndsttr (Feather) (Lucian Remix)
黑海岸壮举。 M. Maggie - Trndsttr (Feather) (Lucian Remix)
黑海岸壮举。 M. Maggie - Trndsttr (Feather) (Lucian Remix)
黑海岸壮举。 M. Maggie - Trndsttr (Feather) Lucian Remix
黑海岸壮举。 M. Maggie Lucian Remix - Trndsttr (Feather)
问题
我提到的表达式适用于所有文件名,除了 Feat... 部分被分组在括号(或括号等)内的情况。
然后我尝试调整 RegEx 以适应聚合条件:
pattern := '^(.+)\s+-\s+(.+?)\s+([\[\(\])?\s*(ft|feat|featuring([\.])?\s+)((.+)[^\]\)\])?\s*(.+)?$'
但我结束了我的脑袋和遗漏的事情,因为它还捕获了第一个括号括起来和后面的字符直到最后。
我需要一些帮助。
问题
我如何修复/改进我的表达式以处理提到的文件名以获得上述预期结果?。
或者换句话说,我需要维护表达式的“结构”,但添加能够在 Feat... 部分位于括号/括号内时捕获它以正确格式化文件名.
PS:请记住,我使用的是 pascal-script 的 RegEx 语法及其限制(我不确定)。
重要编辑:
我发现具有此限制的软件的作者支持从其 pascal 脚本编辑器运行外部应用程序,因此我可以启动用 .Net 编写的 CLI 应用程序来执行正则表达式替换,然后我' m 现在在 C#/Vb.Net RegEx 电机改进下,很好!。
【问题讨论】:
【参考方案1】:类似:
^(?P<artist>.+?(?=\s-\s)) # artist with pos. lookahead
\s-\s # space - space
(?P<title>.+?(?=(?:\(?Feat\.)|$)) # title with pos. lookahead
\(? # optional open parenthesis
(?P<artist2>Feat\.[^()\n]+)? # artist2 with Feat. before
\)? # optional closing parenthesis
(?P<subtitle>.+)?$ # optional subtitle
见a demo on regex101.com。 问题是破折号并不总是匹配(可能是一些额外的编程逻辑?)
【讨论】:
感谢您的回答和为设计表达式所做的努力......但正如我指定的那样,我使用的是 pascal-script,而不是 php 语法及其改进,在删除之前和之后,表达式无法运行编译器说的命名组无法识别修饰符(不完全是在哪里): ^(.+?(?=\s-\s))\s-\s(.+?(?=(?:(?Feat \.)|$))(?(Feat\.[^()\n]+)?)?(.+)?$,你的表达可以适应我的情况\语言?。跨度> 请忘记我所说的关于 pascal-script 的内容,现在我发现具有此限制的软件的作者支持从其 pascal-script 编辑器运行外部应用程序,所以我会开发一个用 C# 编写的简单应用程序,我将开始翻译 PHP 语法,我会来这里接受答案或揭露有关您评论的破折号的任何问题。谢谢大家! 考虑到我的需要,这是带有 .Net 语法的最终正则表达式:"^(?.+?(?=\s*-\s*))\s* -\s*(?以上是关于修复 RegEx 以正确捕获括号内的文本的主要内容,如果未能解决你的问题,请参考以下文章