Javascript 匹配文档块内 JSDoc 标签的正则表达式

Javascript regex to match JSDoc tags inside a documentation block

所以现在我可以隔离代码中的每个 JSDoc(ish)块,例如我在这里有这个块

/// @tag {type} name description
/// description continue
/// another description line
/// @tag {type} name description
/// description continue
/// @tag name description just one line.
/// @tag {type} name

我想使用 Regex 表达式来匹配块内的每个标签标签需要具有 @name 格式然后它可以具有类型 {type} (可选)然后它需要 name 最后它可以有一个描述.. 描述可以是多行的也可以是单行的(也是可选的)。所以

我想出的正则表达式是:

^\/{3} @(?<tag>\w+)(?:[ \t]+{(?<type>.*)})?(?:[ \t]+(?<name>\w+))(?:[ \t]+(?<desc>[\s\S]*))?

我的问题出在描述上,一旦我点击描述,它就不会停在下一个标签的开头...我觉得现在我正在使用贪婪的方法,但我不能找个等待让它不贪心。

所以上面的例子匹配:

标签: tag

姓名: name

描述:

description
/// description continue
/// another description line
/// @tag {type} name description
/// description continue
/// @tag name description just one line.
/// @tag {type} name

我希望描述在新标签开始或块结束时停止

是的,问题是描述匹配器是贪婪的。将 * 更改为 *? 以使其非贪婪修复它。但它仍然存在知道何时停止的问题。您可以通过检查输入是否结束,或者前面是否有 /// @ 来做到这一点。请注意,这包括每个描述行开头的 ///:我认为不可能直接在正则表达式中过滤掉它们,因此您必须 post-process 输出到删除 desc.

中的 ///

/^\/{3} @(?<tag>\w+)(?:[ \t]+{(?<type>.*)})?(?:[ \t]+(?<name>\w+))((?:[ \t]+(?<desc>[\s\S]*?)((?=\/\/\/ @)|\s*\z)))?/gm

使用

/^\/{3} @(?<tag>\w+)(?:[ \t]+{(?<type>[^{}]*)})?[ \t]+(?<name>\w+)(?:[ \t]+(?<desc>.*(?:\n(?!\/{3} @\w).*)*))?/gm

参见regex proof

解释

--------------------------------------------------------------------------------
  ^                        the beginning of the string
--------------------------------------------------------------------------------
  \/{3}                    '/' (3 times)
--------------------------------------------------------------------------------
   @                       ' @'
--------------------------------------------------------------------------------
  (?<tag>                  group and capture to \k<tag>:
--------------------------------------------------------------------------------
    \w+                      word characters (a-z, A-Z, 0-9, _) (1 or
                             more times (matching the most amount
                             possible))
--------------------------------------------------------------------------------
  )                        end of \k<tag>
--------------------------------------------------------------------------------
  (?:                      group, but do not capture (optional
                           (matching the most amount possible)):
--------------------------------------------------------------------------------
    [ \t]+                   any character of: ' ', '\t' (tab) (1 or
                             more times (matching the most amount
                             possible))
--------------------------------------------------------------------------------
    {                        '{'
--------------------------------------------------------------------------------
    (?<type>                group and capture to \k<type>:
--------------------------------------------------------------------------------
      [^{}]*                   any character except: '{', '}' (0 or
                               more times (matching the most amount
                               possible))
--------------------------------------------------------------------------------
    )                        end of \k<type>
--------------------------------------------------------------------------------
    }                        '}'
--------------------------------------------------------------------------------
  )?                       end of grouping
--------------------------------------------------------------------------------
  [ \t]+                   any character of: ' ', '\t' (tab) (1 or
                           more times (matching the most amount
                           possible))
--------------------------------------------------------------------------------
  (?<name>                 group and capture to \k<name>:
--------------------------------------------------------------------------------
    \w+                      word characters (a-z, A-Z, 0-9, _) (1 or
                             more times (matching the most amount
                             possible))
--------------------------------------------------------------------------------
  )                        end of \k<name>
--------------------------------------------------------------------------------
  (?:                      group, but do not capture (optional
                           (matching the most amount possible)):
--------------------------------------------------------------------------------
    [ \t]+                   any character of: ' ', '\t' (tab) (1 or
                             more times (matching the most amount
                             possible))
--------------------------------------------------------------------------------
    (?<desc>                 group and capture to \k<desc>:
--------------------------------------------------------------------------------
      .*                       any character except \n (0 or more
                               times (matching the most amount
                               possible))
--------------------------------------------------------------------------------
      (?:                      group, but do not capture (0 or more
                               times (matching the most amount
                               possible)):
--------------------------------------------------------------------------------
        \n                       '\n' (newline)
--------------------------------------------------------------------------------
        (?!                      look ahead to see if there is not:
--------------------------------------------------------------------------------
          \/{3}                    '/' (3 times)
--------------------------------------------------------------------------------
           @                       ' @'
--------------------------------------------------------------------------------
          \w                       word characters (a-z, A-Z, 0-9, _)
--------------------------------------------------------------------------------
        )                        end of look-ahead
--------------------------------------------------------------------------------
        .*                       any character except \n (0 or more
                                 times (matching the most amount
                                 possible))
--------------------------------------------------------------------------------
      )*                       end of grouping
--------------------------------------------------------------------------------
    )                        end of \k<desc>
--------------------------------------------------------------------------------
  )?                       end of grouping