Проблемы с поиском уникальных значений в regEx - PullRequest
1 голос
/ 06 января 2020

У меня есть javascript regEx, который должен найти все значения с фигурными скобками вокруг них, например {}, и вернуть список уникальных значений. Я думал, что это работает отлично, но я обнаружил, что это не работает в зависимости от последовательности значений.

Например: если целевой документ содержит {lorem} {lorem} {ipsem} {ipsem}, сценарий регистрирует то, что хотел [lorem, ipsem], но {lorem} {ipsem} {ipsem} {lorem} журналы сценариев [lorem, ipsem, lorem]. Что я делаю неправильно!?

function getVariables() {
  var doc = DocumentApp.getActiveDocument();
  var str = doc.getText(); //get the text of the document
  var result = str.match(/{.*?}/g).map(function(val) {
    return val.replace(/[\])}[{(]/g, "");
    //return val.replace(/(^.*\[|\].*$)/g,'');
  });

  //The purpose of sort_unique is to find one of every value or string represented in an array
  function sort_unique(arr) {
    if (result.length === 0) return arr;
    arr = arr.sort(function(a, b) {
      return a * 1 - b * 1;
    });
    var ret = [arr[0]];
    for (var i = 1; i < arr.length; i++) {
      if (arr[i - 1] !== arr[i]) {
        ret.push(arr[i]);
      }
    }

    for (var index = 0; index < ret.length; index++) {
      Logger.log(ret[index]);
    }

    return ret;
  }
  result = sort_unique(result);

  Logger.log("Getting final result for front end....");
  Logger.log(result);

  return result;
}

Ответы [ 3 ]

3 голосов
/ 06 января 2020

Я считаю, что частью вашей проблемы является метод сортировки. Если вы замените

arr = arr.sort(function(a, b) {
  return a * 1 - b * 1;
});

на

arr = arr.sort();

Тогда эта функция будет работать, по крайней мере, на моей стороне.

Это будет работать в O (n log n Время Вы можете добиться большего успеха без сортировки, если сохраните значения, которые вы нашли на карте, а не в массиве. Это будет выполняться за линейное время.

(Также вы захотите заменить if (result.length === 0) return arr; на if (arr.length === 0) return arr; только для того, чтобы ваша sort_unique функция полностью независима от окружающей функции.)

1 голос
/ 06 января 2020

Самый простой способ - использовать Set. Сохраните каждое из совпадений регулярных выражений в наборе, затем верните Array.from(mySet).

var mySet = new Set();
str.match(/{.*?}/g).forEach(function(val) {
  mySet.add(val.replace(/[\])}[{(]/g, ""));
});

return Array.from(mySet);

Функция набора add() равна O(1), поэтому общее время выполнения равно O(n), где n - это количество совпадений в вашей строке. Хотя, реально, поиск по регулярному выражению будет там, где происходит большая часть времени обработки.

0 голосов
/ 06 января 2020

Вы проверяете, совпадают ли последующие элементы и те, которые не являются последующими, в результирующем массиве.

Проверьте, есть ли найденное значение в результате, и, если нет, добавьте совпадение, иначе игнорируйте .

Используйте код, подобный

function getVariables() {
  var doc = DocumentApp.getActiveDocument();
  var str = doc.getText(); //get the text of the document
  var m, result=[], rx = /{([^{}]*)}/g;
  while (m=rx.exec(str)) {
    if (result.indexOf(m[1]) == -1) {
      result.push(m[1]);
    }
  }
  result.sort(); // If you really want to sort use this
  // Logger.log(result); // View the result
}

Регулярное выражение /{([^{}]*)}/g соответствует {, затем захватывает в группу 1 ноль или более символов, отличных от { и }. Итак, значение, которое вам нужно, находится в m[1]. if (result.indexOf(m[1]) == -1) проверяет, находится ли значение в result.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...