c# - 修复 RegEx 以正确捕获括号内的文本

标签 c# .net regex vb.net

场景


前段时间我问了一个在特定条件下格式化音乐文件名的问题:

但是,我发现接受的答案是错误的为时已晚,因为它可以捕获任何以“F”开头的单词。但这不是问题/问题,我只是通过恢复 ft|feat|featuring OR 组解决了它。

所以最后从上面链接的问题中,我最终使用了这个表达式:

pattern := '^(.+)\s+-\s+(.+?)\s+(ft|feat|featuring)[\.\s]*([^([\])]+)(.+)?$' 
replace := '$1 Feat. $4 - $2$5' 

好吧,现在,要测试这些文件名:

  1. 黑海岸 - Trndsttr
  2. 黑色海岸 - Trndsttr(羽毛)
  3. Black Coast - Trndsttr(Lucian Remix)
  4. Black Coast - Trndsttr(羽毛)(Lucian Remix)
  5. Black Coast - Trndsttr 壮举。 M.玛姬
  6. Black Coast - Trndsttr(Feat. M. Maggie)
  7. Black Coast - Trndsttr 壮举。 M. Maggie(卢锡安混音)
  8. Black Coast - Trndsttr(Feat. M. Maggie)(Lucian Remix)
  9. Black Coast - Trndsttr(Lucian Remix)壮举。 M.玛姬
  10. Black Coast - Trndsttr(Lucian Remix)(Feat. M. Maggie)
  11. Black Coast - Trndsttr(羽毛)(Lucian Remix)壮举。 M.玛姬
  12. Black Coast - Trndsttr(Feather)(Lucian Remix)(Feat. M. Maggie)
  13. Black Coast - Trndsttr(羽毛)专长。 M. Maggie(卢锡安混音)
  14. Black Coast - Trndsttr(Feather)(Feat. M. Maggie)(Lucian Remix)
  15. Black Coast - Trndsttr(Feather)(Feat. M. Maggie)Lucian Remix
  16. Black Coast - Trndsttr(羽毛)专长。 M. Maggie Lucian 混音

预期的结果是:

(从1到4没有变化,16是假设的误报,本质上和5、9、11一样。)

  1. 黑海岸 - Trndsttr
  2. 黑色海岸 - Trndsttr(羽毛)
  3. Black Coast - Trndsttr(Lucian Remix)
  4. Black Coast - Trndsttr(羽毛)(Lucian Remix)
  5. 黑色海岸壮举。 M. Maggie - Trndsttr
  6. 黑色海岸壮举。 M. Maggie - Trndsttr
  7. 黑色海岸壮举。 M. Maggie - Trndsttr (Lucian Remix)
  8. 黑色海岸壮举。 M. Maggie - Trndsttr (Lucian Remix)
  9. 黑色海岸壮举。 M. Maggie - Trndsttr (Lucian Remix)
  10. 黑色海岸壮举。 M. Maggie - Trndsttr (Lucian Remix)
  11. 黑色海岸壮举。 M. Maggie - Trndsttr(羽毛)(Lucian Remix)
  12. 黑色海岸壮举。 M. Maggie - Trndsttr(羽毛)(Lucian Remix)
  13. 黑色海岸壮举。 M. Maggie - Trndsttr(羽毛)(Lucian Remix)
  14. 黑色海岸壮举。 M. Maggie - Trndsttr(羽毛)(Lucian Remix)
  15. 黑色海岸壮举。 M. Maggie - Trndsttr (Feather) 卢西安混音
  16. 黑色海岸壮举。 M. Maggie Lucian Remix - Trndsttr(羽毛)

问题


我提到的表达式适用于所有文件名,除了 Feat... 部分被分组在圆括号(或括号等)内的情况。

然后我尝试根据聚合条件调整正则表达式:

pattern := '^(.+)\s+-\s+(.+?)\s+([\[\(\{])?\s*(ft|feat|featuring([\.])?\s+)((.+)[^\]\)\}])?\s*(.+)?$'

但我最终搞砸了我的头脑并遗漏了一些东西,因为它还捕获了第一个圆括号和后面的字符,直到最后。

我需要一些帮助。

问题


我如何修复/改进我的表达以处理上述文件名以获得上述预期结果?

或者换句话说,我需要维护表达式的“结构”,但添加捕获 Feat... 部分的能力,当它在圆括号/方括号内时,以正确格式化文件名.

PS:请记住我在 pascal-script 的 RegEx 语法及其限制下(我不确定)。

重要编辑:

我发现具有此限制的软件的作者支持从其 pascal 脚本编辑器运行外部应用程序,因此我可以启动一个用 .Net 编写的 CLI 应用程序来执行正则表达式替换,然后我'我现在在 C#/Vb.Net RegEx 电机改进下,很好!

最佳答案

类似于:

^(?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 .
问题是破折号并不总是匹配(也许是一些额外的编程逻辑?)

关于c# - 修复 RegEx 以正确捕获括号内的文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35553961/

相关文章:

java - 用正则表达式按索引将一个字符替换为其他字符?

c# - ASP.NET 有没有办法获取所有单例?

c# - 什么能在 .NET 2 上运行,什么不能运行?

用于正式逻辑格式的 Java 正则表达式

javascript - 通过 javascript 检索隐藏字段值

c# - 如何检查应用程序是否有权访问目录?

Java Regex - 使用 String 的 replaceAll 方法替换换行符

c# - IQueryable.Distinct() 与 List.Distinct()

c# - 在winforms中使用.dll文件

c# - .NET 紧凑型框架 - "offline webservices"支持