【问题标题】:Perform substitution on regex results, but only on a given condition对正则表达式结果执行替换,但仅在给定条件下
【发布时间】:2013-01-12 05:01:44
【问题描述】:

首先,让我澄清一下,我对正则表达式一无所知,但我需要为 MusicBrainz Picard 编写一个“标记脚本”,这样它就不会影响我格式化曲目某些方面的方式' 标题。

这是我需要做的: - 查找括号内的所有子字符串 - 然后,对于那些满足给定条件且仅匹配的匹配项,将括号更改为方括号

例如,考虑这个字符串: DJ Fresh - Louder (Sian Evans) (Flux Pavilion & Doctor P Remix)

它需要像这样改变: DJ Fresh - Louder (Sian Evans) [Flux Pavilion & Doctor P Remix]

条件是如果括号内的字符串包含子字符串“dj”或“mix”或“version”或“inch”等......那么它周围的括号需要更改为括号。

所以,问题是: 是否可以创建一个可以执行此操作的正则表达式?

非常感谢您。

【问题讨论】:

  • 无论谁回答这个问题,musicbrainz 都使用 Python 正则表达式语法。

标签: regex musicbrainz


【解决方案1】:

假设没有嵌套括号,您可以使用以下正则表达式来搜索文本:

(?i)\((?=[^()]*(?:dj|mix|version|inch))([^()]+)\)

请注意,正则表达式不区分大小写,因为前面有(?i) - 删除它使其区分大小写

检查您的语言的语法,看看您是否可以使用 r 前缀,例如r'literal_string',指定文字字符串。

并使用以下内容作为替换:

[$1]

您可以通过在(?:dj|mix|version|inch) 部分添加关键字来包含更多关键字,每个关键字由| 分隔。如果关键字包含()[]|.+?*$$$ @、{} 你需要避开它们(我 99% 确定这个列表是详尽的)。一个更简单的考虑方法是:如果关键字只包含空格和字母数字(但请注意空格的数量是严格的),您可以将它们添加到正则表达式中而不会产生副作用。


剖析正则表达式:

  • (?i)不区分大小写模式

  • \(:( 是正则表达式中的特殊字符,需要在前面加上\ 进行转义。

  • (?=[^()]*(?:dj|mix|version|inch)):正向预测(?=pattern)

    • [^()]*:我需要检查文本是否在括号内,而不是在括号外或其他括号内,因此我使用否定字符类 [^characters] 以避免匹配 () 并溢出当前括号。我所做的假设也在这里发挥了作用。

    • (?:dj|mix|version|inch):关键字列表,位于非捕获组 (?:pattern)| 表示交替。

  • ([^()]+):关于没有嵌套括号的假设使得匹配括号内的所有字符更容易。文本被捕获以供以后替换,因为(pattern) 是捕获组,而不是(?:pattern)

  • \):)是正则表达式中的特殊字符,需要在\前面加上转义。

【讨论】:

  • 我认为这取决于语言,但严格来说,替换应该只是 [$1],因为替换正则表达式中没有 [](即没有字符类)。
  • @dicarlo2:正在编辑并意识到这一点。无论如何,感谢您指出这一点。
  • @xfx:请仔细阅读假设和说明以添加关键字。请注意,如果输入不满足假设,解决方案将无法正常工作。
  • @dicarlo2:你说得对,我必须删除替换正则表达式的转义括号......
  • 感谢您的补充说明;我真的很感激。我可以确认,到目前为止,它运行良好。这是我最终使用插件的结果代码: metadata["title"] = re.sub(r"((?=[^()]*(?:dj|mix|version|inch|edit|radio)) ([^()]+))", r"[\1]", metadata["title"], flags=re.IGNORECASE)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-25
  • 1970-01-01
相关资源
最近更新 更多