1

我有一个字符串,看起来类似于以下 'test:1;hello:five;just:23'。使用此字符串,我需要能够执行以下操作。

....
var test = MergeTokens('test:1;hello:five;just:23', 'yes:23;test:567');
...

最终结果应该是 'test:567;hello:five;just:23;yes:23' (注意标记的确切顺序并不重要)。

只是想知道是否有人对如何解决这个问题有任何聪明的想法。我在想对右边的每个标记进行正则表达式替换,如果因为不匹配而没有发生替换,只需附加它。但也许有更好的方法。

干杯安东尼

编辑:右侧应覆盖左侧。左边是原来的内容,右边是新内容。另一种看待它的方式是,如果它们不存在于右侧,则仅将标记保留在左侧,并将所有标记保留在右侧。

@Ferdinand 感谢您的回复。问题是您提出的解决方案的效率。我最初考虑过类似的路线,但由于合并的 O(n*z) 复杂性(其中 n 和 z 分别是左侧和右侧的数字标记),更不用说拆分和连接了。

因此,为什么我试图查看正则表达式的路径。也许在幕后,正则表达式同样糟糕或更糟,但是有一个正则表达式从右侧存在的左侧字符串中删除任何令牌(O(n)右侧令牌的总量),然后只需添加2串在一起(即vat test = test1 + test2)似乎更有效。谢谢

4

3 回答 3

6

我将使用join()split()创建一些实用程序函数来将您的令牌数据打包和解包到一个对象:

// Unpacks a token string into an object.
function splitTokens(str) {
    var data = {}, pairs = str.split(';');
    for (var i = 0; i < pairs.length; ++i) {
        var pair = pairs[i].split(':');
        data[pair[0]] = pair[1];
    }
    return data;
}

// Packs an object into a token string.
function joinTokens(data) {
    var pairs = [];
    for (var key in data) {
        pairs.push(key + ":" + data[key]);
    }
    return pairs.join(';');
}

使用这些,合并很容易:

// Merges all token strings (supports a variable number of arguments).
function mergeTokens() {
    var data = {};
    for (var i = 0; i < arguments.length; ++i) {
        var d = splitTokens(arguments[i]);
        for (var key in d) {
            data[key] = d[key];
        }
    }
    return joinTokens(data);
}

如果您想提取一些键(比如“测试”)和/或检查是否存在,实用程序函数也很有用:

var data = splitTokens(str);
if (data["test"] === undefined) {
    // Does not exist
} else {
    alert("Value of 'test': " + data["test"]);
}
于 2009-03-29T12:55:53.720 回答
0

以下是我结束思考的内容。你们怎么看?

谢谢安东尼

function Tokenizer(input, tokenSpacer, tokenValueSpacer) {
    this.Tokenizer = {};
    this.TokenSpacer = tokenSpacer;
    this.TokenValueSpacer = tokenValueSpacer;
    if (input) {
        var TokenizerParts = input.split(this.TokenSpacer);
        var i, nv;
        for (i = 0; i < TokenizerParts.length; i++) {
            nv = TokenizerParts[i].split(this.TokenValueSpacer);
            this.Tokenizer[nv[0]] = nv[1];
        }
    }
}

Tokenizer.prototype.add = function(name, value) {
    if (arguments.length == 1 && arguments[0].constructor == Object) {
        this.addMany(arguments[0]);
        return;
    }
    this.Tokenizer[name] = value;
}

Tokenizer.prototype.addMany = function(newValues) {
    for (nv in newValues) {
        this.Tokenizer[nv] = newValues[nv];
    }
}

Tokenizer.prototype.remove = function(name) {
    if (arguments.length == 1 && arguments[0].constructor == Array) {
        this.removeMany(arguments[0]);
        return;
    }
    delete this.Tokenizer[name];
}

Tokenizer.prototype.removeMany = function(deleteNames) {
    var i;
    for (i = 0; i < deleteNames.length; i++) {
        delete this.Tokenizer[deleteNames[i]];
    }
}

Tokenizer.prototype.MergeTokenizers = function(newTokenizer) {
    this.addMany(newTokenizer.Tokenizer);
}

Tokenizer.prototype.getTokenString = function() {
    var nv, q = [];
    for (nv in this.Tokenizer) {
        q[q.length] = nv + this.TokenValueSpacer + this.Tokenizer[nv];
    }
    return q.join(this.TokenSpacer);
}

Tokenizer.prototype.toString = Tokenizer.prototype.getTokenString;
于 2009-03-30T02:37:42.527 回答
0

我晚了几年,但我认为这就是你要找的:

function MergeTokens(input, replace){
 var replaceTokens = replace.split(";");
 for(i=0; i<replaceTokens.length; i++){
  var pair = replaceTokens[i].split(":");
  var result = input;
  regString = "\\b" + pair[0] + ":[\\w]*\\b";
  var reg = new RegExp(regString);
  if(reg.test(result)){
   result = result.replace(reg, replaceTokens[i]);
  }
  else{
   result = result + replaceTokens[i];
  }
 }
 return result;
}
于 2010-10-05T04:49:02.363 回答