【问题标题】:How can I shorten this regex for JavaScript?如何缩短 JavaScript 的这个正则表达式?
【发布时间】:2011-05-24 20:37:06
【问题描述】:

基本上我只是希望它匹配() 中的任何东西。我尝试了.*,但它们似乎不起作用。现在我的正则表达式看起来像:

\(([\\\[\]\-\d\w\s/*\.])+\)

它将匹配的字符串是 URL 路由,例如:

#!/foo/bar/([a-z])/([\d\w])/(*)

在这个例子中,我上面的正则表达式匹配:

  • ([a-z])

  • ([\d\w])

  • (*)

    奖励: 我怎样才能使它仅在以( 开头并以) 结尾时匹配。我以为我在前面使用了^\($,最后是\),但没有运气。 无视这个奖金。没想到没关系……

【问题讨论】:

    标签: javascript regex optimization


    【解决方案1】:

    您是否担心嵌套括号?如果没有,您可以将其设置为匹配所有不是右括号的字符:

    \(([^)]*)\)
    

    【讨论】:

      【解决方案2】:

      基本上我只是希望它匹配() 中的任何东西
      奖励:我怎样才能使它仅在以 ( 开头并以 ) 结尾时匹配?

      简单易懂。

      var re1 = /^\(.*\)$/
      // or
      var re2 = new RegExp('^\\(.*\\)$');
      

      编辑

      回复:@Mike Samuel'scmets

      不匹配括号之间的换行符,这些换行符在原始文件中由 \s 显式匹配。
      ...
      也许你应该使用[\s\S] 而不是.
      ...
      如果您要排除换行符,您应该有意或明确地这样做。

      请注意,. 匹配除换行符以外的任何单个字符。如果您还想匹配换行符作为括号之间“任何内容”的一部分,请使用 [\s\S] 字符类:

      var re3 = /^\([\s\S]*\)$/
      // or
      var re4 = new RegExp('^\\([\\s\\S]*\\)$');
      

      【讨论】:

      • 不匹配括号之间的换行符,这些换行符在原始文件中由\s 明确匹配。
      • m 影响^$ 的行为,而不是.。您正在考虑s,它在 perl 但不是 JavaScript。也许你应该使用[\s\S] 而不是.
      • 是的,我总是忘记 m 的确切作用(而且我很少这样做)所以我恢复了。从什么时候开始在 URL 路由中需要换行符?
      • @Matt 如果您要排除换行符,您应该有意或明确地这样做。解释换行符被排除但 URLS 中不允许的其他字符的注释或警告将是完全足够的。否则,阅读本文的人会觉得您正在解决 OP 中要求的“任何事情”。
      • @马特。迷人的。 [\s\S] 中的 re4 应该是 [\\s\\S]。在一个挑剔的笔记上,. 不包括多个换行符;相当于[^\r\n\u2028\u2029]
      【解决方案3】:

      要否定匹配,请使用[^...] 构造。因此,要匹配括号内的任何内容,您可以使用:

      \([^)]+\)
      

      表示“匹配任何以左括号开头、包含任意数量的右括号并以右括号结尾的字符。

      要匹配与上述结构匹配的整行,只需将其包装为 ^$

      ^\([^)]+\)$
      

      【讨论】:

        【解决方案4】:

        我不完全确定我理解你在做什么,但试试这个:

        var re = /\/(\([^()]+\)(?=\/|$)/;
        

        匹配开头的斜杠和开头的括号可确保括号确实位于开头。你不能在最后做同样的事情,因为你不知道会有 一个斜杠。如果有,您不想使用它,因为它也是下一次匹配尝试的前导斜线。

        相反,您使用前瞻 - (?=\/|$) - 匹配尾部斜杠而不消耗它。如果没有斜线,我假设也不应该出现其他字符 - 因此锚点:$

        @patorjk 提出了一个很好的观点:最外面的一对之间可以有更多的括号吗?如果有,问题就复杂得多。我不会费心尝试扩展我的正则表达式来处理嵌套的括号;一些正则表达式风格可以处理这样的事情,但不是 JavaScript。相反,我会推荐这个草率的正则表达式:

        \/(\([\s\S]+?\))(?=\/|$)
        

        我说“草率”是因为它依赖于序列/()/ 永远不会出现在有效匹配中的假设。与我的第一个正则表达式一样,您感兴趣的文本(即除前导斜杠和尾随斜杠之外的所有文本)将被捕获到第 1 组中。

        请注意非贪心量词。使用常规的贪婪量词,它将一次性匹配从第一个 ( 到最后一个 ) 的所有内容。换句话说,它将匹配([a-z])/([\d\w])/(*),而不是您想要的([a-z])([\d\w])(*)

        【讨论】:

          猜你喜欢
          • 2020-01-09
          • 1970-01-01
          • 2017-08-11
          • 1970-01-01
          • 1970-01-01
          • 2013-12-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多