在2个字符串中搜索占位符值

时间:2019-05-15 07:43:26

标签: javascript jquery regex string object

我在JavaScript中有两个字符串,例如

var description = "<DP_A>.<Del.Dce Lks.{Link}>.<Pl.Rrs Bk 0.310-PT-304_({strm})>"

var Title = "<DP_A>.<Del.Dce Lks.1>.<Pl.Rrs Bk 0.310-PT-304_(1)>"

此处{Link}和{strm}是占位符,或者{}之间的任何东西都是占位符

我需要比较描述和标题之类的字符串以查找占位符值,输出需要类似

 {"Link" : 1, "strm" : 1 }

或数组

[{Link" : 1, "strm" : 1}]

我已经尝试过一些RegEx,但是没有用,有什么帮助吗?

 if (description.includes("{")) {
                        var found = [],          // an array to collect the strings that are found
                         rxp = /{([^}]+)}/g,
                         curMatch;
                        while (curMatch = rxp.exec(description)) {
                            found.push(curMatch[1]);
                        }

                       }

我能够获取占位符数组,但无法在标题字符串中找到值。

3 个答案:

答案 0 :(得分:2)

您可以获取所有部分,然后从标题字符串中拼接出值。

"<DP_A>.<Del.Dce Lks.{Link}>.<Pl.Rrs Bk 0.310-PT-304_({strm})>",
"<DP_A>.<Del.Dce Lks. 1    >.<Pl.Rrs Bk 0.310-PT-304_( 1    )>";

function getParts(pattern, values) {
    var result = {}, value, p1, p2 = 0;
    (pattern.match(/[^{}]+/g) || []).forEach((s, i, a) => {
        if (i % 2) return Object.assign(result, { [s]: value });
        p1 = values.indexOf(s, p2),
        p2 = values.indexOf(a[i + 2], p1);
        value = values.slice(p1 + s.length, p2 === -1 ? undefined : p2);
    });
    return result;
}

var description = "<DP_A>.<Del.Dce Lks.{Link}>.<Pl.Rrs Bk 0.310-PT-304_({strm})>{last}",
    title = "<DP_A>.<Del.Dce Lks.abcdef>.<Pl.Rrs Bk 0.310-PT-304_(ghijklöööö)>fubar";
    
console.log(getParts(description, title));

使用for语句并重用已知职位。

function getParts(pattern, values) {
    var parts = pattern.match(/[^{}]+/g),
        result = {}, p1, p2, i;
    if (!parts || parts.length < 2) return {};
    p1 = values.indexOf(parts[0]);
    for (i = 1; i < parts.length; i += 2) {
        p2 = values.indexOf(parts[i + 1], p1);
        Object.assign(result, { [parts[i]]: values.slice(p1 + parts[i - 1].length, p2 === -1 ? undefined : p2) });
        p1 = p2;
    }
    return result;
}

var description = "&lt;DP_A&gt;.&lt;Del.Dce Lks.{Link}&gt;.&lt;Pl.Rrs Bk 0.310-PT-304_({strm})&gt;{last}",
    title = "&lt;DP_A&gt;.&lt;Del.Dce Lks.abcdef&gt;.&lt;Pl.Rrs Bk 0.310-PT-304_(ghijklöööö)&gt;fubar";
    
console.log(getParts(description, title));

答案 1 :(得分:0)

使用replace

var description = "&lt;DP_A&gt;.&lt;Del.Dce Lks.{Link}&gt;.&lt;Pl.Rrs Bk 0.310-PT-304_({strm})&gt;"
const obj = { 
  Link: 1,
  strm: 2
};
const res = description.replace(/{(.*?)}/g, m => obj[m.slice(1, -1)]);

document.write(res);

答案 2 :(得分:0)

好的,这比我实际预期的要复杂得多。

我实际上并不擅长这种操作,但是这是一个“可行的”解决方案:您可能需要重写一下,但实际上,这个概念对我来说很公平。

要获得结果,遵循的步骤是:

  • 获取“ {”的所有索引。我在下面使用了函数生成器,但是您可以使用任何其他所需的条件。我们的目标是获得每场比赛的开始。
  • 循环查找每个匹配的括号,查找右括号并获取描述字符串中紧随其后的字符。
  • 对Title字符串执行值匹配。
  • 继续应用当前匹配的值以更新偏移量。
  • 映射结果以收集所需的输出:由于一个占位符可能存在两次,因此我有意返回了一组项目。

一些注意事项:

  • 如上所述,以下脚本不会处理“ {hello {world}”之类的限制情况。
  • 可以通过匹配前一个字符和下一个字符来改进以下脚本。
  • 下面的脚本在某些情况下可能会失败,只是在这种情况下才起作用,但是我没有在极限情况下对其进行测试。

var description = "&lt;DP_A&gt;.&lt;Del.Dce Lks.{Link}&gt;.&lt;Pl.Rrs Bk 0.310-PT-304_({strm})&gt;";
var Title = "&lt;DP_A&gt;.&lt;Del.Dce Lks.1&gt;.&lt;Pl.Rrs Bk 0.310-PT-304_(1)&gt;";

// Acquire all the indexes of every "{".
// BEWARE: This will actually fail if the description is "&LT{LLT{hello}", but you may change this.
const descriptionLookupIndexes = [].concat(...(function*(){
  for (var i = 0; i < description.length; i++) {
     if (description[i] === "{") yield [i];
  }
})());

let matches = [];
descriptionLookupIndexes.forEach((i, index) => {
  // acquire the description by replacing the currently known values.
  let _replacedDescription = description;
  let _replacedDescriptionIndex = i - matches.reduce((a,b) => a + b.amount, 0);
  // This foreach will replace the placeholders already found with their respective values.
  matches.forEach(k => {
    let splitted = _replacedDescription.split('');
    splitted.splice(k.from, k.amount, [k.value.split('')]);
    _replacedDescription = splitted.join('');
  });
  // Acquire the relevant portion of the string.
  const needle = _replacedDescription.substring(_replacedDescriptionIndex, _replacedDescription.length);
  // Look for the next character after the first } occurrence in the current substring.
  const nextChar = needle[needle.indexOf("}") + 1];
  // Acquire the relevant substring for the title.
  const titleNeedle = Title.substring(_replacedDescriptionIndex, Title.length);
  matches.push({
    from: _replacedDescriptionIndex,
    amount: needle.match(/[^{\}]+(?=})/g)[0].length + 1,
    needle: needle.match(/[^{\}]+(?=})/g)[0],
    value: titleNeedle.substring(0, titleNeedle.indexOf(nextChar))
  });
});

// Matches is now the array with all the occurrences, let's just map it to acquire a new array of objects with the desired format.
// BEWARE: If multiple keys exists, they will be mapped to an array.

const res = matches.reduce((acc, next) => {
  acc[next.needle] = acc[next.needle] || [];
  acc[next.needle].push({
    [next.needle]: next.value
  });
  return acc;
}, {});
console.log(res);