如果它被一个字符包围,请不要替换正则表达式

时间:2013-03-28 13:26:39

标签: javascript jquery regex

我想将-括起来的所有字符串替换为~所包围的字符串,但如果此字符串再次被*括起来则不会。

例如,这个字符串......

The -quick- *brown -f-ox* jumps.

......应该成为......

The ~quick~ *brown -f-ox* jumps.

我们看到-只有在*<here>*时才会被替换。

我的javascript-regex现在(不管它是否被*包围):

var message = source.replace(/-(.[^-]+?)-/g, "~$1~");

编辑:请注意,可能存在奇数*秒。

4 个答案:

答案 0 :(得分:2)

这与正则表达式有点棘手。我想我会做的是这样的事情:

var msg = source.replace(/(-[^-]+-|\*[^*]+\*)/g, function(_, grp) {
  return grp[0] === '-' ? grp.replace(/^-(.*)-$/, "~$1~") : grp;
});

<强> jsFiddle Demo

查找 -*组,并仅在虚线上执行替换。通常,“嵌套”语法对正则表达式具有挑战性(或不可能)。 (当然,作为对问题说明的评论,有一些特殊情况 - 悬挂元字符 - 这也使这一点复杂化。)

答案 1 :(得分:1)

我会通过基于*拆分数组然后只替换偶数索引来解决它。匹配不平衡的星星比较棘手,它涉及知道最后一个项目索引是奇数还是偶数:

'The -quick- *brown -f-ox* jumps.'
    .split('*')
    .map(function(item, index, arr) { 
        if (index % 2) {
            if (index < arr.length - 1) {
                return item; // balanced
            }
            // not balanced
            item = '*' + item;
        }
        return item.replace(/\-([^-]+)\-/, '~$1~');
    })
    .join('');

Demo

答案 2 :(得分:1)

查明匹配是否不是包含在某些分隔符中是一项非常复杂的任务 - 另请参阅this exampleLookaround可以提供帮助,但JS只支持前瞻。因此,我们可以将“未被~ ”包围,重写为“后跟偶数或~ ”,然后匹配:

source.replace(/-([^-]+)-(?=[^~]*([^~]*~[^~]*~)*$)/g, "~$1~");

但最好我们在-*上进行匹配,这样我们就可以使用*中包含的任何内容,然后可以在回调函数中决定不替换它:< / p>

source.replace(/-([^-]+)-|\*([^*]+)\*/g, function(m, hyp) {
    if (hyp) // the first group has matched
        return "~"+hyp+"~";
    // else let the match be unchanged:
    return m;
});

这样做的好处是能够更好地指定“封闭的”,例如通过在“内部”添加单词边界,更好地处理无效模式(例如@Maras提到的奇数*字符) - 当前的正则表达式只需要接下来两次出现。

答案 3 :(得分:0)

杰克非常明确的回答。

source.split(/(\*[^*]*\*)/g).map(function(x,i){
return i%2?x:x.replace(/-/g,'~');
}).join('');

似乎工作, 欢呼声。