【问题标题】:Search Placeholder Values in 2 strings在 2 个字符串中搜索占位符值
【发布时间】:2019-10-02 06:49:21
【问题描述】:

我在 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}]

我尝试了一些正则表达式但不起作用,有什么帮助吗?

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

                       }

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

【问题讨论】:

  • 向我们展示您迄今为止尝试过的内容,即使这不起作用。
  • 每次都是同一个字符串吗?
  • {"Link" : 1, "strm" : 2 } 为什么是“strm”2?它只出现一次。 我需要比较诸如描述和标题之类的字符串以查找占位符值,您是什么意思?你需要找到每个的索引吗?
  • @briosheje - strm 对我来说应该等于1,但不是因为它的出现次数,而是因为在Title 中,它被写成1 其中{strm}放在description
  • @KévinBibollet 哦。不错的猜测。不过,这解释得很糟糕。那么,这比预期的要难。

标签: javascript jquery regex string object


【解决方案1】:

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

"<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 ) ({strm}) 相同?..
  • 你指的长度是多少?
  • 您在 ( 1 )&amp;gt;"; 上匹配 ({strm})&amp;gt;",但 OP 字符串以 (1)&amp;gt;" 结尾。不确定是否是有意的。
  • @NinaScholz 没有看到您的示例实际上更复杂,抱歉:P
【解决方案2】:

使用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);

【讨论】:

  • 我认为他正在尝试匹配标题字符串 inside 的占位符,正如 Kevin 在 cmets 中提到的那样。
【解决方案3】:

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

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

实现结果所遵循的步骤是:

  • 获取“{”的所有索引。我在下面使用了一个函数生成器,但是您可以使用任何其他您想要的标准。目标是获得每场比赛的首发。
  • 循环每个匹配的括号,查找右括号并获取描述字符串中紧随其后的字符。
  • 对 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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-30
    相关资源
    最近更新 更多