AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题 / 79489705
Accepted
Milos Stojanovic
Milos Stojanovic
Asked: 2025-03-06 22:38:52 +0800 CST2025-03-06 22:38:52 +0800 CST 2025-03-06 22:38:52 +0800 CST

正则表达式从字符串中删除诸如“官方视频”,“音频”,“音乐视频”等子字符串

  • 772

我正在尝试清除 YouTube 视频标题中不必要的单词,例如“官方视频”、“音频”、“音乐视频”等。我需要帮助构建可以使用的正则表达式。到目前为止,我尝试过:

const regex = /\s*[-\(\[]?\s*(-|official|video|audio|lyrics|lyric|hd|full|4k|music\s+video|\d{4})\s*[\)\]]?$/gi;

据我了解,这只会删除最后一次出现的关键字。我所做的是在这样的循环中使用它:

function clearSearchTerm(title) {
    const regex = /\s*[-\(\[]?\s*(-|official|video|audio|lyrics|lyric|hd|full|4k|music\s+video|\d{4})\s*[\)\]]?$/gi;
    let newTitle;

    do {
        newTitle = title;
        title = title.replace(regex, "");
    } while (newTitle !== title);

    return title;
}

目前它对我来说是有效的,因为我没有找到任何它不起作用的例子。评论中提到的是,我以前的正则表达式会删除出现在标题中间的关键字,我猜这个问题已经解决了。如果你知道如何改进这一点,我洗耳恭听。在下一部分中,我将写一些我需要删除的示例。

我想要删除的单词如下:

Audio
Video
Lyrics
Official
Remaster
2020 (or years in general)
...

所有这些词(可能还有更多)都可以出现在(and之间)或[and之间]或之后-。这些词可以组合在一起,例如:Some title - Official Videowhich should be cleaned to beSome title等等。

javascript
  • 2 2 个回答
  • 101 Views

2 个回答

  • Voted
  1. Best Answer
    Patrick Janser
    2025-03-07T19:29:38+08:002025-03-07T19:29:38+08:00

    使用 PCRE(通常在 PHP 中),您可以通过声明子模式来避免单词重复,然后在主模式中重复使用它。还可以使用 x标志添加注释和空格以提高可读性:

    /
    (?(DEFINE)
      (?<words_to_drop>
        (?:
          \s*
          \b(?:Official|Video|Audio|Music|Lyrics?|Remaster(?:ed)?|HD|LP|HQ|4k|Full|Version)\b
          \s*
        )+
      )
    )
    # Finishing by - and words to remove (but not years).
    \s+[-–]\s+\g<words_to_drop>$
    | # or
    # Words or years to remove between brackets or parenthesis.
    \s*[[(](?:\g<words_to_drop>|\s*\d{4}\s*)+[\])]
    /ix
    

    查看其实际作用和解释:https://regex101.com/r/kPeYzb/1

    如果您必须坚持使用 JavaScript 引擎,则必须删除空格、注释并复制粘贴单词的模式,从而得到相同的模式,具有 JavaScript 风格:

    const pattern = /\s+[-–]\s+(?:\s*\b(?:Official|Video|Audio|Music|Lyrics?|Remaster(?:ed)?|HD|LP|HQ|4k|Full|Version)\b\s*)+$|\s*[[(](?:(?:\s*\b(?:Official|Video|Audio|Music|Lyrics?|Remaster(?:ed)?|HD|LP|HQ|4k|Full|Version)\b\s*)+|\s*\d{4}\s*)+[\])]/gi;
    

    具体操作如下:https://regex101.com/r/kPeYzb/2

    现在,关于避免在正则表达式中输入两次此单词列表的问题,可以使用RegExp()构造函数从字符串创建正则表达式。这意味着您可以从配置中获得一个单词数组(或单词正则表达式):

    const input = document.getElementById('input');
    const output = document.getElementById('output');
    
    // Original commented regular expression : https://regex101.com/r/kPeYzb/1
    
    // We will build this regular expression from a custom list of words,
    // for example taken from a configuration page.
    const wordsToRemove = [
      'Official',
      'Video',
      'Audio',
      'Music',
      'Lyrics?',
      'Remaster(?:ed)?',
      'HD',
      'LP',
      'HQ',
      '4k',
      'Full',
      'Version'
    ];
    // IMPORTANT: compared to the regex syntax, if we build a RegExp instance
    //            from a string, each backslash should be escaped.
    // The regex to match multiple words from this list of words to remove.
    const regexWordsToRemove = '(?:\\s*\\b(?:' + wordsToRemove.join('|') + ')\\b\\s*)+';
    // The full regex pattern.
    const patternCleanup = '\\s+[-–]\\s+' + regexWordsToRemove + '$|\\s*[[(](?:' + regexWordsToRemove + '|\\s*\\d{4}\\s*)+[\\])]';
    // Create the regex object.
    const regexCleanup = new RegExp(patternCleanup, 'gmi');
    // Printing it should give the same result as the original regex we
    // made here: https://regex101.com/r/kPeYzb/2
    console.log(regexCleanup);
    
    function updateOutput() {
      output.value = input.value.replace(regexCleanup, '');
    }
    
    document.addEventListener('DOMContentLoaded', (loaded) => {
      // When the input changes, update the output text.
      input.addEventListener('input', updateOutput);
      
      // Update the output for the initial input value.
      updateOutput();
    });
    body {
      font-family: Arial, sans-serif;
    }
    
    .two-cols {
      display: grid;
      grid-template-columns: 1fr 1fr;
      grid-column-gap: .5em;
    }
    
    textarea {
      /* Just because the snippet space is small. */
      font-size: 0.8em;
      /* Don't wrap the text, to make comparaison easier. */
      white-space: pre;
      overflow-wrap: normal;
      overflow-x: scroll;
      box-sizing: border-box;
      width: 100%;
    }
    
    textarea[readonly] {
      color: #666;
      background: #f8f8f8;
    }
    <form id="clean-up" class="two-cols" action="#">
    
      <div>
        <label for="input">Input:</label>
        <textarea id="input" name="input"
                  placeholder="Put your text here"
                  rows="10">Some title - Official Video
    Some title [Official Video]
    Some title (Official Video)
    The Buggles - Video killed the Radio Star
    The Smashing Pumpkins - 1979 (Official Music Video)
    The Smashing Pumpkins – 1979
    1979 (Remastered 2012)
    New Order – 1963 (Lyrics)
    Paul Davis - '65 Love Affair (1981 LP Version HQ)
    Pulp - Disco 2000</textarea>
      </div>
      
      <div>
        <label for="output">Output: <small>Automatically updated</small></label>
        <textarea id="output" name="output"
                  placeholder="Modified text" readonly
                  rows="10"></textarea>
      </div>
      
    </form>

    • 3
  2. rich neadle
    2025-03-07T05:56:15+08:002025-03-07T05:56:15+08:00

    此正则表达式将匹配-或[或(后跟任意数量的文字空格 ,后跟任意单词OFFICIAL VIDEO|REMASTER|LYRICS|AUDIO或四位数字,后跟任意数量的空格,后跟匹配的右括号(当适用时)。

    REGEX 模式(ECMAScript(JavaScript)风格)(标志:gmi):

    (?:-|\((?:(?<=\()(?= *[^)\n]+ *\)))|\[(?:(?<=\[)(?= *[^\]\n]+ *\]))) *(?:OFFICIAL VIDEO|REMASTER|LYRICS|AUDIO|\d{4})\s*(?:\]|\))?(?= |\n|$)
    

    正则表达式演示: https://regex101.com/r/Wy2I0w/8 (10 个匹配)

    笔记:

    • (|\[(?:(?<=\[)(?= *[^\]\n]* *\])))
    • (?:打开非捕获组(?:...) 交替 (...|...|...)语句。匹配交替语句中由竖线 ( |) 分隔的元素之一。
    • -匹配文字破折号-(第一个选项)
    • |替代元素分隔符。后跟第二个选项。
    • \(匹配文字(
    • (?:开始非捕获组(?:...)(第二个选项)
    • (?<=开始后视 (?<=...)检查是否打开(。
    • \(匹配文字(。此字符必须位于此索引点之前。
    • )仔细后视。
    • (?=开始前瞻 (?=...)以确保有匹配的结束符)。不会消耗字符。
    • *匹配 0 个或多个 ( *) 文字空格 。
    • [^)\n]+ 否定捕获类 [^...]匹配任何不是)或换行符 的字符\n1 次或多次(+)。
    • *匹配 0 个或多个 ( *) 文字空格 。
    • \)匹配文字)。
    • )关闭前瞻。
    • )关闭非捕获组(第二种选择)
    • |替代元素分隔符。后跟第三个选项。
    • \[匹配文字[。
    • (?: 开始非捕获组(?:...)(第三个选项)
    • (?<=开始回顾 (?<=...)检查是否打开。
    • \[匹配文字[。
    • )关闭*回顾。
    • (?=开始向前查找匹配的结束括号]。不会消耗字符。
    • *匹配0个或多个文字空格 。
    • [^\]\n]+ 否定字符类匹配任何不是]或换行符 的字符\n一次或多次 ( +)。
    • *匹配文字空格 0 次或更多次。
    • \]匹配文字]。
    • )关闭前瞻。
    • )关闭非捕获组。
    • )关闭交替组。
    • *匹配0个或多个文字空格 。
    • (?:开始包含交替的非捕获组。
    • OFFICIAL VIDEO|REMASTER|LYRICS|AUDIO|\d{4} 交替匹配列出的单词之一或四位数字\d{4}(年份)。
    • )关闭非捕获组。
    • \s*匹配0个或更多空白字符\s。
    • (?:打开包含交替的非捕获组。
    • \]|\)匹配文字]或 文字)。
    • )?关闭交替组。使其成为可选的 ( ?)。
    • (?=开始前瞻,不会消耗字符。
    • |\n|$匹配文字空格字符 、换行符\n或行尾$。
    • )关闭前瞻。

    测试字符串:

    FIRST title - Official Video 
    SECOND title [Official VIDEO]
    THIRD title (Lyrics) 
    FOURTH title - Remaster
    FIFTH title - [ Audio ]
    SIXTH title ( Lyrics ) 
    SEVENTH title (2020) 
    EIGHT title (1999)
    NINTH title (20)
    TENTH title [ 2002 ]
    ELEVENTH title [ 200 ]
    TWELFTH  title ( 1999 )
    THIRTEENTH  title ( Official Lyrics )
    FOURTEENTH  title ( Official VIDEO]
    FOURTEENTH  title ( Official VIDEO
    FOURTEENTH  title [Official VIDEO)
    FOURTEENTH  title Official VIDEO]
    

    结果:

    FIRST title 
    SECOND title 
    THIRD title  
    FOURTH title 
    FIFTH title - 
    SIXTH title  
    SEVENTH title  
    EIGHT title 
    NINTH title (20)
    TENTH title 
    ELEVENTH title [ 200 ]
    TWELFTH  title 
    THIRTEENTH  title ( Official Lyrics )
    FOURTEENTH  title ( Official VIDEO]
    FOURTEENTH  title ( Official VIDEO
    FOURTEENTH  title [Official VIDEO)
    FOURTEENTH  title Official VIDEO]
    
    • 0

相关问题

  • 合并排序不起作用 - Javascript代码:即使在调试后也无法找到错误

  • select.remove() 方法工作得很奇怪[关闭]

  • useOpenWeather() 中总是出现 401 res -react-open-weather lib [重复]

  • 输入元素没有只读属性,但字段仍然不可编辑[关闭]

  • 如何编辑 D3.js RadialTree 的第一个节点半径?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    重新格式化数字,在固定位置插入分隔符

    • 6 个回答
  • Marko Smith

    为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会?

    • 2 个回答
  • Marko Smith

    VScode 自动卸载扩展的问题(Material 主题)

    • 2 个回答
  • Marko Smith

    Vue 3:创建时出错“预期标识符但发现‘导入’”[重复]

    • 1 个回答
  • Marko Smith

    具有指定基础类型但没有枚举器的“枚举类”的用途是什么?

    • 1 个回答
  • Marko Smith

    如何修复未手动导入的模块的 MODULE_NOT_FOUND 错误?

    • 6 个回答
  • Marko Smith

    `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它?

    • 3 个回答
  • Marko Smith

    在 C++ 中,一个不执行任何操作的空程序需要 204KB 的堆,但在 C 中则不需要

    • 1 个回答
  • Marko Smith

    PowerBI 目前与 BigQuery 不兼容:Simba 驱动程序与 Windows 更新有关

    • 2 个回答
  • Marko Smith

    AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String”

    • 1 个回答
  • Martin Hope
    Fantastic Mr Fox msvc std::vector 实现中仅不接受可复制类型 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant 使用 chrono 查找下一个工作日 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor 构造函数的成员初始化程序可以包含另一个成员的初始化吗? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský 为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul C++20 是否进行了更改,允许从已知绑定数组“type(&)[N]”转换为未知绑定数组“type(&)[]”? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann 为什么 {2,3,10} 和 {x,3,10} (x=2) 的顺序不同? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller 在 5.2 版中,bash 条件语句中的 [[ .. ]] 中的分号现在是可选的吗? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench 为什么双破折号 (--) 会导致此 MariaDB 子句评估为 true? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng 为什么 `dict(id=1, **{'id': 2})` 有时会引发 `KeyError: 'id'` 而不是 TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String” 2024-03-20 03:12:31 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve