Javascript 正则表达式:将字符串与具有相同模式的子字符串匹配

Javascript 正则表达式:将字符串与具有相同模式的子字符串匹配,javascript,regex,coffeescript,Javascript,Regex,Coffeescript,我试图将一个字符串与一个模式匹配,这个模式可以包含具有相同模式的子字符串 下面是一个示例字符串: 尼加拉瓜[[注|注|刚果从1999年起成为ICCROM的成员,尼加拉瓜从1971年起成为ICCROM的成员。由于连续六个日历年未缴纳会费,ICCROM大会于2013年11月暂停了这两个国家的活动(ICCROM[[规约s | url | www.ICCROM.org/about/Statutes/],第9条)。]。另一个[[link | url | google.com]]可能会出现 以下是模式: [

我试图将一个字符串与一个模式匹配,这个模式可以包含具有相同模式的子字符串

下面是一个示例字符串:

尼加拉瓜[[注|注|刚果从1999年起成为ICCROM的成员,尼加拉瓜从1971年起成为ICCROM的成员。由于连续六个日历年未缴纳会费,ICCROM大会于2013年11月暂停了这两个国家的活动(ICCROM[[规约s | url | www.ICCROM.org/about/Statutes/],第9条)。]。另一个[[link | url | google.com]]可能会出现

以下是模式:

[[display_text|code|type|content]]
因此,我想要的是得到括号内的字符串,然后在顶层中寻找更多与模式匹配的字符串

我想要的是匹配这个:

  • [[注| s |注|刚果从1999年起成为ICCROM的成员,尼加拉瓜从1971年起成为ICCROM的成员。由于连续六个日历年未缴纳会费,ICCROM大会于2013年11月暂停了这两个成员国的资格(ICCROM[[规约s | url | www.ICCROM.org/about/Statutes/],第9条)。]
  • 1.1[[法规| s | url | www.iccrom.org/about/Statutes/]

  • [[link | s | url | google.com]]
  • 我使用的是这个
    /(\[\[.]]])/
    ,但直到最后一个
    ]]
    之前,它都能得到所有东西

    我想要的是能够识别匹配的字符串并将其转换为HTML元素,其中
    | note |
    将是一个blockquote标记和
    | url
    一个
    一个
    标记。因此,blockquote标记可以包含link标记

    顺便说一句,我用咖啡脚本来做


    提前感谢。

    一般来说,regex不擅长处理嵌套表达式。如果您使用贪婪模式,它们将匹配太多,如果您使用非贪婪模式,正如@bjfletcher所建议的,它们将匹配太少,停止在外部内容中。这里的“传统”方法是一种基于令牌的解析器,您可以逐个遍历字符并构建一个抽象语法树(AST),然后根据需要重新格式化

    我在这里使用的一种略显粗糙的方法是将字符串转换为JSON字符串,并让JSON解析器完成转换为嵌套对象的艰苦工作:


    这将为您提供一个字符串和结构化对象的数组,然后您可以通过格式化程序运行该数组来输出所需的HTML。格式化程序留给用户作为练习:)。

    一个快速的,添加?在.*之后,为了使其不贪婪:)@bjfletcher-不起作用,它将捕获内部嵌套表达式的结尾。@nrabinowitz似乎打算捕获第一个]],而不是最后一个]],因此是非贪婪的operator@bjfletcher我尝试了
    *?
    并在第一次出现
    ]
    时停止,这是另一个
    ]
    的内部,就在我的例子的第9条
    前面。。这是一种不同的方法,但实际上很有意义,甚至在我系统的其他地方也可能有用。我星期一试试,然后告诉你。谢谢:)顺便说一句,@nrabinowitz我没有高估你的答案,因为我还没有足够的声誉。。。对不起:/
    
    function toPoorMansAST(s) {
        // escape double-quotes, as they'll cause problems otherwise. This converts them
        // to unicode, which is safe for JSON parsing.
        s = s.replace(/"/g, "\u0022");
        // Transform to a JSON string!
        s =
            // Wrap in array delimiters
            ('["' + s + '"]')
            // replace token starts
            .replace(/\[\[([^\|]+)\|([^\|]+)\|([^\|]+)\|/g,
                 '",{"display_text":"$1","code":"$2","type":"$3","content":["')
            // replace token ends
            .replace(/\]\]/g, '"]},"');
    
        return JSON.parse(s);
    }