用于标记字符串的RegEx解析器

时间:2014-12-30 20:33:45

标签: 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 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循环来做到这一点,但它会变得太乱。有什么建议吗?

1 个答案:

答案 0 :(得分:2)

正则表达式无法处理嵌套表达式(除非您可以访问强大的正则表达式实现,javascript没有这样做),所以纯粹的正则表达式解决方案是不可能的。但仍有一种简单的方法可以做到这一点:

  1. 替换\{(\w+)\}((?:(?!\{\w+\}).)*)\{\/\1\}的所有出现(这与{tag}...{/tag}对匹配,但只有在{tag}不包含其他00b4f[ $2 00b4d]时)。
  2. 重复,直到没有更多匹配。

  3. 要使其动态化,请使用回调函数进行替换:

    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);
    }