Подтвердить что ты не робот

Как определить следующие шаблоны кода

У меня есть шаблон js promises, который я хочу определить для нескольких ключевых слов

Например, если я ставлю код вроде:

var deferred = Q.defer();

И в файле у меня есть также следующее значение

deferred.reject(err);
deferred.resolve();
return deferred.promise;

Полный код

ПРИМЕР 1

function writeError(errMessage) {
    var deferred = Q.defer();
    fs.writeFile("errors.log", errMessage, function (err) {
        if (err) {
            deferred.reject(err);
        } else {
            deferred.resolve();
        }
    });
    return deferred.promise;
}

И я хочу, чтобы, если я поместил большой файл кода (как строку) , чтобы найти, что этот файл содержит шаблон

Другой пример

var d = Q.defer();/* или $q.defer */

И в файле у вас есть также следующее значение

d.resolve(val);
d.reject(err); 
return d.promise;

Полный пример 2

function getStuffDone(param) {           
    var d = Q.defer(); /* or $q.defer */ 

    Promise(function(resolve, reject) {
        // or = new $.Deferred() etc.        
        myPromiseFn(param+1)                 
        .then(function(val) { /* or .done */ 
            d.resolve(val);                  
        }).catch(function(err) { /* .fail */ 
            d.reject(err);                   
        });                                  
        return d.promise; /* or promise() */ 

}                  

Существуют открытые источники, которые можно использовать для проведения такого анализа (предоставить шаблон, и он найдет...)

Есть еще несколько сложных шаблонов с childProcess, но пока это нормально  :)

4b9b3361

Ответ 1

ОБНОВЛЕНИЕ. Я сделал одну коррекцию для кода, т.е. изменил set[2] на set[set.length - 1], чтобы разместить наборы запросов любого размера. Затем я применил тот же алгоритм к вашим двум примерам.

Решение, которое я предоставляю, соответствует некоторым правилам, которые я считаю разумными для типа поиска, который вы предлагаете. Предположим, вы ищете четыре строки, ABCD (без учета регистра, поэтому он найдет ABCD или abcd или aBcD):

  • Множество наборов соответствия можно найти в одном файле, то есть найти два набора в ABCDabcd.
  • Regex используется для отдельных строк, что означает, что варианты могут быть включены. (Как только одно из последствий этого, не имеет значения, есть ли у вас комментарий в конце соответствующей строки в вашем коде.)
  • Обрабатываемые шаблоны всегда должны быть на разных линиях, например. A и B не могут находиться в одной строке.
  • Соответствующий набор должен быть полным, например. он не найдет ABC или ABD.
  • Соответствующий набор должен быть непрерывным, т.е. он не найдет ничего в ABCaD. (Важно отметить, что это также означает, что не найдет что-либо в перекрывающихся наборах, например ABCaDbcd. Можно утверждать, что это слишком ограничивает. Однако в этом примере, который должен быть найден, ABCD или abcd? Ответ произволен и произволен сложно описать. Более того, на основе приведенных вами примеров такое перекрытие обычно не ожидается, поэтому этот краевой случай кажется маловероятным, что делает это ограничение разумным.)
  • Соответствующий набор должен быть внутренне не повторяющимся, например. он не найдет ABbCD. Однако, с AaBCD, он найдет набор, т.е. Найдет aBCD.
  • Встраиваемые наборы разрешены, но будет найден только внутренний. с ABabcdCD, будет найдено только abcd.

В приведенном ниже фрагменте кода показан пример поиска. Он не демонстрирует всех случаев краев. Тем не менее, он показывает общую функциональность.

var queryRegexStrs = [
  "I( really)? (like|adore) strawberry",
  "I( really)? (like|adore) chocolate",
  "I( really)? (like|adore) vanilla"
];

var codeStr =
  "....\n" +
  "Most people would say 'I like vanilla'\n" +
  "....\n" +
  "....\n" +
  "....\n" +
  "....\n" +
  "Amir taste profile:\n" +
  "....\n" +
  "I like strawberry\n" +
  "....\n" +
  "....\n" +
  "I told Billy that I really adore chocolate a lot\n" +
  "....\n" +
  "I like vanilla most of the time\n" +
  "....\n" +
  "Let me emphasize that I like strawberry\n" +
  "....\n" +
  "....\n" +
  "....\n" +
  "....\n" +
  "Juanita taste profile:\n" +
  "....\n" +
  "I really adore strawberry\n" +
  "I like vanilla\n" +
  "....\n" +
  "....\n" +
  "....\n" +
  "....\n" +
  "Rachel taste profile:\n" +
  "I adore strawberry\n" +
  "....\n" +
  "Sometimes I like chocolate, I guess\n" +
  "....\n" +
  "I adore vanilla\n" +
  "....\n" +
  "....\n" +
  "....\n" +
  "....\n" +
  "";

// allow for different types of end-of-line characters or character sequences
var endOfLineStr = "\n";

var matchSets = search(queryRegexStrs, codeStr, endOfLineStr);





function search(queryRegexStrs, codeStr, endOfLineStr) {

  // break the large code string into an array of line strings
  var codeLines = codeStr.split(endOfLineStr);

  // remember the number of lines being sought
  var numQueryLines = queryRegexStrs.length;

  // convert the input regex strings into actual regex in a parallel array
  var queryRegexs = queryRegexStrs.map(function(queryRegexStr) {
    return new RegExp(queryRegexStr);
  });

  // search the array for each query line
  //   to find complete, uninterrupted, non-repeating sets of matches

  // make an array to hold potentially multiple match sets from the same file
  var matchSets = [];

  // prepare to try finding the next match set
  var currMatchSet;

  // keep track of which query line number is currently being sought
  var idxOfCurrQuery = 0;

  // whenever looking for a match set is (re-)initialized,
  //   start looking again for the first query,
  //   and forget any previous individual query matches that have been found
  var resetCurrQuery = function() {
    idxOfCurrQuery = 0;
    currMatchSet = [];
  };

  // check each line of code...
  codeLines.forEach(function(codeLine, codeLineNum, codeLines) {

    // ...against each query line
    queryRegexs.forEach(function(regex, regexNum, regexs) {

      // check if this line of code is a match with this query line
      var matchFound = regex.test(codeLine);

      // if so, remember which query line it matched
      if (matchFound) {

        // if this code line matches the first query line,
        //   then reset the current query and continue
        if (regexNum === 0) {
          resetCurrQuery();
        }

        // if this most recent individual match is the one expected next, proceed
        if (regexNum === idxOfCurrQuery) {

          // temporarily remember the line number of this most recent individual match
          currMatchSet.push(codeLineNum);

          // prepare to find the next query in the sequence
          idxOfCurrQuery += 1;

          // if a whole query set has just been found, then permanently remember
          //   the corresponding code line numbers, and reset the search
          if (idxOfCurrQuery === numQueryLines) {
            matchSets.push(currMatchSet);
            resetCurrQuery();
          }

          // if this most recent match is NOT the one expected next in the sequence,
          //   then start over in terms of starting to look again for the first query
        } else {
          resetCurrQuery();
        }
      }
    });
  });

  return matchSets;

}




// report the results
document.write("<b>The code lines being sought:</b>");
document.write("<pre>" + JSON.stringify(queryRegexStrs, null, 2) + "</pre>");
document.write("<b>The code being searched:</b>");
document.write(
  "<pre><ol start='0'><li>" +
  codeStr.replace(new RegExp("\n", "g"), "</li><li>") +
  "</li></ol></pre>"
);
document.write("<b>The code line numbers of query 'hits', grouped by query set:</b>");
document.write("<pre>" + JSON.stringify(matchSets) + "</pre>");
document.write("<b>One possible formatted output:</b>");

var str = "<p>(Note that line numbers are 0-based...easily changed to 1-based if desired)</p>";
str += "<pre>";
matchSets.forEach(function(set, setNum, arr) {
  str += "Matching code block #" + (setNum + 1) + ": lines " + set[0] + "-" + set[set.length - 1] + "<br />";
});
str += "</pre>";
document.write(str);

Ответ 2

Следующее регулярное выражение может выглядеть немного страшно, но было построено из простых понятий и позволяет немного больше свободы, чем вы упомянули - например, дополнительные пробелы, разные имена переменных, отсутствие var и т.д. Кажется, что работа для обоих примеров - посмотрите, соответствует ли она вашим потребностям.

([^\s\r\n]+)\s*=\s*(?:Q|\$q)\.defer\s*\(\s*\)\s*;(?:\r?\n|.)*(?:\s|\r?\n)(?:\1\.reject\(\w+\)\s*;(?:\r?\n|.)*(?:\s|\r?\n)\1\.resolve\(\s*\w*\)\s*;|\1\.resolve\(\s*\w*\)\s*;(?:\r?\n|.)*(?:\s|\r?\n)\1\.reject\(\w+\)\s*;)(?:\r?\n|.)*(?:\s|\r?\n)return\s+(?:\1\.)?promise\s*;

Regular expression visualization

Демоверсия Debuggex