Javascript 类标记字符串的RegExp解析器

Javascript 类标记字符串的RegExp解析器,javascript,regex,replace,Javascript,Regex,Replace,在我正在编写的应用程序中,我希望能够使用RegExp解析类似于标记的字符串,以便对其进行修改,例如: "{b}This is BOLD{/b}".replace(/\{b\}(.*?)\{\/b\}/gi, "00b3f[ $1 00b3d]"); // Returns "00b3f[ This is BOLD 00b3d]" 我可以很容易地做到这一点,但当一个更复杂的字符串传递给函数时,它会变得复杂,例如: "{red} This is RED {red} This also should

在我正在编写的应用程序中,我希望能够使用RegExp解析类似于标记的字符串,以便对其进行修改,例如:

"{b}This is BOLD{/b}".replace(/\{b\}(.*?)\{\/b\}/gi, "00b3f[ $1 00b3d]");

// Returns "00b3f[ This is BOLD 00b3d]"
我可以很容易地做到这一点,但当一个更复杂的字符串传递给函数时,它会变得复杂,例如:

"{red} This is RED {red} This also should be red {/red} and this {/red}"
.replace(/\{red\}(.*?)\{\/red\}/gi, "00b4f[ $1 00b4d]");

// Returns:
// "00b4f[  This is RED {red} This also should be red  00b4d] and this {/red}"

// Where the output should be:
// "00b4f[  This is RED 00b4f[ This also should be red 00b4d] and this 00b4d]"

我想用一个简单的RegExp解决这个问题,但是我找不到一个方法!我想我可以用一个while循环来做这个,但它会变得太混乱。有什么建议吗?

Regex无法处理嵌套表达式(除非您可以访问强大的Regex实现,而javascript没有),因此纯Regex解决方案是不可能的。但仍然有一个简单的方法可以做到这一点:

  • 00b4f[$200b4d]
    替换所有出现的
    {(\w+)}((?:(?!{\w+})。*){\/\1\}
    (这与
    {tag}…{/tag}{/code>对匹配,但前提是它不包含另一个
    {tag}
    )对
  • 重复此操作,直到不再有匹配项

  • 要使其成为动态的,请对替换使用回调函数:

    var tagPattern = /\{(\w+)\}((?:(?!\{\w+\}).)*)\{\/\1\}/g,
        tagReplacer = function ($0, $1, $2) {
            switch ($1) {
                case "b": return "00b3f[" + $2 + " 00b3d]";
                case "red": return "00b4f[" + $2 + " 00b4d]";
                default: return $2;
            }
        };
    
    while (tagPattern.test(sourceString)) {
        sourceString = sourceString.replace(tagPattern, tagReplacer);
    }
    

    使用regexp无法解决这个问题,因为您描述的语言是上下文敏感的,但不是规则的——简单地说,它意味着“您需要内存来解析它”,这就是您所观察到的。我推荐一个简单的递归下降解析器。你可以通过提到替换回调来扩展这一点,我非常确定OP将需要它们。+1非常非常酷。一个小的while循环和一个回调将使它非常动态,并且易于实现@Tomalak:我从来没有真正使用过JavaScript,所以OP对替换回调的了解可能比我多。@Rawing我冒昧地添加了这一点。@Tomalak:在这种情况下,我将冒昧地对您的评论进行投票,至少是这样。非常感谢。