Regex, чтобы соответствовать определению функции JavaScript и убедиться, что она что-то возвращает? - PullRequest
1 голос
/ 13 сентября 2011

Мне нужно убедиться, что в некотором переданном коде определена функция с именем mapfn и что эта функция возвращает результат.Я придумал следующее регулярное выражение: mapfn\s+?\=\s+?function\s+?\(split\)\s+?\{.+?return\(result\).+?\}, которое соответствует чему-то вроде

mapfn = function (split) {
    var i = 5+4;
    for (var j = 0; j < 10; j++) {
        i += j*Math.random()*10;
    }
    var result = i;
    return(result)
}

Что желательно, но если я пойду к примеру компилятора замыкания с этим кодом и получу что-то вроде mapfn=function(){for(var b=9,a=0;a<10;a++)b+=a*Math.random()*10;return b};, эторегулярное выражение бесполезно.Кроме того, пользователь отправляет что-то вроде

function mapfn (split) {
    var i = 5+4;
    for (var j = 0; j < 10; j++) {
        i += j*Math.random()*10;
    }
    var result = i;
    return(result)
}

Тогда регулярное выражение также бесполезно.

Мне кажется, что есть более элегантное решение этой проблемы, чем наличие 5 или 6 регулярных выражений для этой работы ипытаясь сопоставить любой из них.

Ответы [ 2 ]

8 голосов
/ 13 сентября 2011

Это полностью невозможно сделать с регулярным выражением.

Рассмотрим

function x() { if (1 < 0) return 7; }

Все, что вы можете сделать, - это проанализировать функцию в среде Javascript, вызвать ееи посмотрим, что он вернет.

Если вы хотите убедиться, что оно всегда возвращает значение, вам нужно решить проблему остановки .

2 голосов
/ 13 сентября 2011

SLaks - это правильно, но вам не нужно вызывать проблему остановки, чтобы доказать, что это невозможно с регулярными выражениями .С помощью регулярного выражения вы даже не сможете определить, содержит ли функция JavaScript return, используемое в качестве ключевого слова, даже если вы можете сопоставить фигурные скобки, чтобы указать, где заканчивается функция определения.

Рассмотрим

function () {
  1 /[/**/]; return 1 ///
}

против

function () {
    /[/**/]; return 1 ///  
}

Первый содержит возврат, потому что он эквивалентен

function () {
  1 / [];
  return 1;
  ///
}

, а второй нет, потому что он эквивалентен

function () {
  new RegExp("[\\/\\*\\*\\/]; return 1 ");
  //
}

Между /* и */ может быть произвольно много символов, поэтому вам необходимо полностью устранить неоднозначность первого /, чтобы определить, является ли это оператором деления или регулярным выражением, чтобы определить, встречается ли ключевое слово return вфункция.Это требует полного разбора, а JavaScript не имеет регулярной лексической грамматики.

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