javascript - 在 JavaScript 正则表达式中使用前瞻匹配可选组

标签 javascript regex regex-greedy regex-lookarounds

我正在尝试使用正则表达式解决字符串匹配问题。我需要匹配这种形式的 URL:

http://soundcloud.com/okapi23/dont-turn-your-back/

我需要“拒绝”这种形式的 URL:

http://soundcloud.com/okapi23/sets/happily-reversed/

尾随的“/”显然是可选的。

所以基本上:

  • 在主机名之后,可以有 2 或 3 个组,如果第二组等于 "sets",则正则表达式不应匹配。
  • “集” 可以包含在 URL 中的任何其他位置
  • "sets" 需要完全匹配

到目前为止我想到的是 http(s)?://(www\.)?soundcloud\.com/.+/(?!sets)\b(/.+)?,失败了。

有什么建议吗?是否有任何库可以简化任务(例如,使尾部斜线可选)?

最佳答案

假设 OP 想要测试给定字符串是否包含满足以下要求的 URL:

  • URL 方案必须是 http:https:
  • URL 权限必须是 //soundcloud.com//www.soundcloud.com
  • URL 路径必须存在并且必须包含 2 或 3 个路径段。
  • 第二个路径段不能是:“sets”
  • 每个路径段必须包含一个或多个仅由字母数字字符组成的“单词”([A-Za-z0-9]),并且多个单词仅由一个破折号或下划线分隔。
  • URL 不能包含查询或片段部分。
  • URL 路径可以以可选的 "/" 结尾。
  • URL 应区分大小写。

这是一个经过测试的 JavaScript 函数(带有完整注释的正则表达式),它可以解决问题:

function isValidCustomUrl(text) {
    /* Here is the regex commented in free-spacing mode:
    # Match specific URL having non-"sets" 2nd path segment.
    ^                          # Anchor to start of string.
    https?:                    # URL Scheme (http or https).
    //                         # Begin URL Authority.
    (?:www\.)?                 # Optional www subdomain.
    soundcloud\.com            # URL DNS domain.
    /                          # 1st path segment (can be: "sets").
    [A-Za-z0-9]+               # 1st word-portion (required).
    (?:                        # Zero or more extra word portions.
      [-_]                     # only if separated by one - or _.
      [A-Za-z0-9]+             # Additional word-portion.
    )*                         # Zero or more extra word portions.
    (?!/sets(?:/|$))           # Assert 2nd segment not "sets".
    (?:                        # 2nd and 3rd path segments.
      /                        # Additional path segment.
      [A-Za-z0-9]+             # 1st word-portion.
      (?:                      # Zero or more extra word portions.
        [-_]                   # only if separated by one - or _.
        [A-Za-z0-9]+           # Additional word-portion.
      )*                       # Zero or more extra word portions.
    ){1,2}                     # 2nd path segment required, 3rd optional.
    /?                         # URL may end with optional /.
    $                          # Anchor to end of string.
    */
    // Same regex in javascript syntax:
    var re = /^https?:\/\/(?:www\.)?soundcloud\.com\/[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)*(?!\/sets(?:\/|$))(?:\/[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)*){1,2}\/?$/i;
    if (re.test(text)) return true;
    return false;
}

关于javascript - 在 JavaScript 正则表达式中使用前瞻匹配可选组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13032074/

相关文章:

php - 我需要一个用另一个标签替换一个标签的 php 正则表达式

java - 如何拆分字符串并包含拆分器?

regex - 我不明白正则表达式

javascript - 无法使用 Chrome 开发者工具查看 localStorage key

javascript - 如何将类似 JSON 的字符串转换为 Javascript 对象?

javascript - Dropzone js 不会触发 ajax 调用

javascript - 方括号内的交替运算符不起作用

regex - 不包含特定字符串的正则表达式

c++ - Boost regex 不替换在 regex 网站上正确替换的表达式

javascript - 表单有效时更改背景图像