Почему мой Regex создает внутреннюю ошибку сервера с «++», а не какую-либо другую комбинацию специальных символов? - PullRequest
0 голосов
/ 16 января 2019

Я пытаюсь создать базовый поиск, который будет возвращать результаты из базы данных Mongo. Запрос должен соответствовать значениям, которые являются либо полным значением, либо внутри значения. Например, поиск C должен вернуть C, C#, C++. Кроме того, Java должен возвращать оба Java, Javascript. В настоящее время у меня настроена простая реализация, которая может выполнить это, однако, если я ищу запрос C++, мне возвращается внутренняя ошибка сервера. Поиск C+ вернет успешный поиск с C++ в списке. Это происходит только с ++ в запросе, так как поиск с двойными специальными символами (//, --, $$, etc.) вернется успешно.

Я пытался использовать функцию Javascript RegExp для достижения этой цели, однако я новичок в регулярных выражениях и уверен, что именно отсюда и возникла моя проблема. Текущая реализация

  1. Получает поисковый запрос из ввода и кодирует его
  2. Передает запрос контроллеру, который применяет функцию RegExp
  3. Находит результаты в базе данных и возвращает результаты в объекте JSON

AJAX Позвоните для поиска

function getSearchResults() {
    var query = $("#searchInput").val(); //search value
    if(query === '') {
        return false;
    } else {
        $.ajax({
            url: '/items/search?search=' + encodeURIComponent(query), //url with search query
            type: 'GET',
            dataType: 'json',
            beforeSend: function() {
                $('#loadingOverlay').css('visibility', 'visible');
            },
            success: function(result) {
                $('#itemContentMain').bootstrapTable({data: result});
                $('#itemContentMain').bootstrapTable('load', result);
                $('#loadingOverlay').css('visibility', 'hidden');
            }
        }).fail(function (xhr, ajaxOptions, thrownError){
            alert("The search failed to return results: " + thrownError);
        });
    }
    return false;
}

Контроллер

itemController.search = function(req, res) {
    var regexEx = new RegExp(req.query.search, "i"); //ignore case
    Item.find({ $or: [{name: regexEx}, {category: regexEx}, {subcategory: regexEx},
        {status: regexEx}, {description: regexEx}]}).exec(function (err, items) {
        if (err) {
            console.log("Error:", err);
        } else {
            console.log("Search returning results");
            res.send(items);
        }
   });
};

Я читал, что ++ в Regex - это квантификатор Possessive, так что, если двигатель не сработает, не вернется и попытается отменить найденные совпадения. Однако когда запрос достигает функции RegExp, он кодируется как /items/search?search=%2B%2B. Что происходит, когда в запросе передается ++, и как я могу уменьшить внутреннюю ошибку сервера, которую он вызывает?

1 Ответ

0 голосов
/ 16 января 2019

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

Использование этой функции источник :

function escapeRegExp(string) {
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}

Вы можете заменить:

var regexEx = new RegExp(req.query.search, "i"); //ignore case

с

var regexEx = new RegExp(escapeRegExp(req.query.search), "i"); //ignore case
                         ^^^^^^^^^^^^

Вы можете легко повторить ошибку, создав простое регулярное выражение: /c++/ в консоли браузера, которое выдаст следующее сообщение (может варьироваться в зависимости от браузера):

SyntaxError: нечего повторять


Примечание : это довольно плохая идея, чтобы позволить пользователю искать необработанный ввод.

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