修复RegEx以正确捕获括号

时间:2016-02-22 12:39:45

标签: c# .net regex vb.net

SCENARIO

以前我问了一个问题,在某些条件下格式化音乐文件名:

但是,我注意到接受的答案是错误的,因为它可以捕获以“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. 黑色海岸 - Trndsttr(羽毛)(Lucian Remix)
  5. Black Coast - Trndsttr Feat。 M. Maggie
  6. Black Coast - Trndsttr(Feat.M。Maggie)
  7. Black Coast - Trndsttr Feat。 M. Maggie(Lucian Remix)
  8. Black Coast - Trndsttr(Feat.M。Maggie)(Lucian Remix)
  9. Black Coast - Trndsttr(Lucian Remix)壮举。 M. Maggie
  10. Black Coast - Trndsttr(Lucian Remix)(Feat.M。Maggie)
  11. 黑色海岸 - Trndsttr(羽毛)(Lucian Remix)壮举。 M. Maggie
  12. Black Coast - Trndsttr(Feather)(Lucian Remix)(Feat.M。Maggie)
  13. 黑色海岸 - Trndsttr(Feather)Feat。 M. Maggie(Lucian Remix)
  14. Black Coast - Trndsttr(Feather)(Feat.M。Maggie)(Lucian Remix)
  15. Black Coast - Trndsttr(Feather)(Feat.M。Maggie)Lucian Remix
  16. 黑色海岸 - Trndsttr(Feather)Feat。 M. Maggie Lucian Remix
  17. 预期结果如下:

    (从1到4没有变化,16是可假设的假阳性,它实质上与5,9和11相同。)

    1. 黑色海岸 - Trndsttr
    2. 黑色海岸 - Trndsttr(羽毛)
    3. Black Coast - Trndsttr(Lucian Remix)
    4. 黑色海岸 - Trndsttr(羽毛)(Lucian Remix)
    5. Black Coast Feat。 M. Maggie - Trndsttr
    6. Black Coast Feat。 M. Maggie - Trndsttr
    7. Black Coast Feat。 M. Maggie - Trndsttr(Lucian Remix)
    8. Black Coast Feat。 M. Maggie - Trndsttr(Lucian Remix)
    9. Black Coast Feat。 M. Maggie - Trndsttr(Lucian Remix)
    10. Black Coast Feat。 M. Maggie - Trndsttr(Lucian Remix)
    11. Black Coast Feat。 M. Maggie - Trndsttr(羽毛)(Lucian Remix)
    12. Black Coast Feat。 M. Maggie - Trndsttr(羽毛)(Lucian Remix)
    13. Black Coast Feat。 M. Maggie - Trndsttr(羽毛)(Lucian Remix)
    14. Black Coast Feat。 M. Maggie - Trndsttr(羽毛)(Lucian Remix)
    15. Black Coast Feat。 M. Maggie - Trndsttr(羽毛)Lucian Remix
    16. Black Coast Feat。 M. Maggie Lucian Remix - Trndsttr(羽毛)
    17. 问题

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

      然后我尝试使RegEx适应攻击条件:

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

      但是我结束了弄乱我的头并丢失了东西,因为它还捕获了第一个括号外壳和下面的字符直到最后。

      我需要一些帮助。

      问题

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

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

      PS:请记住,我使用的是pascal-script的RegEx语法及其限制(我不确定它们)。

      重要编辑:

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

1 个答案:

答案 0 :(得分:2)

类似的东西:

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