Поиск значений заполнителей в 2 строках - PullRequest
2 голосов
/ 15 мая 2019

У меня есть две строки в 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 ]

2 голосов
/ 15 мая 2019

Вы можете получить все части и затем склеить значения из строки заголовка.

"<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));
0 голосов
/ 15 мая 2019

Хорошо, это намного сложнее, чем я ожидал.

На самом деле я не очень хорош в подобных операциях, но вот «рабочее» решение: вы можете немного его переписать, но, тем не менее, концепция на самом деле справедлива для меня.

Шаги для достижения результатов:

  • Получить все индексы "{". Я использовал генератор функций ниже, но вы можете использовать любые другие критерии, которые вы хотите. Цель состоит в том, чтобы получить стартовую сетку каждого матча.
  • Зациклите каждую подходящую скобку, найдите закрывающую скобку и получите символ сразу после него в строке описания.
  • выполнить сопоставление значений в строке заголовка.
  • Продолжите, применяя текущие согласованные значения для обновления смещений.
  • Сопоставьте результат, чтобы получить желаемый результат: я намеренно возвратил массив элементов, потому что заполнитель может существовать дважды.

Некоторые примечания:

  • Приведенный ниже скрипт, как уже упоминалось выше, не будет заботиться о предельных случаях, таких как "{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);
0 голосов
/ 15 мая 2019

Использование 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...