Используйте обратную косую черту в knex raw

#node.js #escaping #knex.js

Вопрос:

У меня есть пример кода с использованием knex raw:

 let reg = '((.*?)'
const result = await knex.raw(`select *, regexp(code, '${reg}', 1,1,null,1) from test ...`);
 

И запрос knex генерирует запрос

 select *, regexp(code, '((.*?)', 1,1,null,1) from test ...
 

->> Отсутствует обратная косая черта

когда я изменяю переменные reg на let reg = '\((.*?\)'

создание запроса knex :

 select *, regexp(code, '\((.*?\)', 1,1,null,1) from test ...
 

-> Двойная обратная косая черта

Я хочу, чтобы мой запрос knex генерировал запрос с одной обратной косой чертой :

 select *, regexp(code, '((.*?)', 1,1,null,1) from test ...
 

Пожалуйста, помогите мне!

Ответ №1:

То, о чем вы просите, не имеет смысла. Чтобы процитировать руководство MySQL:

Чтобы использовать буквальный экземпляр специального символа в регулярном выражении, предшествуйте ему двумя символами обратной косой черты ( ). Анализатор MySQL интерпретирует одну из обратных косых черт, а библиотека регулярных выражений интерпретирует другую. Например, для сопоставления строки 1 2, содержащей специальный символ , правильным является только последнее из следующих регулярных выражений:

 mysql> SELECT REGEXP_LIKE('1 2', '1 2');                       -> 0
mysql> SELECT REGEXP_LIKE('1 2', '1 2');                      -> 0
mysql> SELECT REGEXP_LIKE('1 2', '1\ 2');
 

Таким образом, двойная обратная косая черта является правильным выводом, одиночная обратная косая черта вообще ничего не сделает.

Однако вы даже не должны получать этот вывод из строкового литерала с двойными обратными косыми чертами, вставленными в запрос (без использования ? заполнителя), поэтому я предполагаю, что вы неправильно истолковываете вывод, возможно, он является частью объекта или иным образом уже снова закодирован как строковый литерал JS. Чтобы получить правильный вывод двойных обратных косых черт, вам нужно либо использовать четырехкратные обратные косые черты в строковом литерале, либо использовать параметризованный запрос.

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

Ответ №2:

Попробуйте это

 let reg = '\((.*?\)'
const result = await knex.raw(`select *, regexp(code, '?', 1,1,null,1) from test ...`, [reg]);
 

Комментарии:

1. Это не логично, строковый литерал JS '((.*?)' просто вычислит ((.*?) и создаст ошибку линтера по пути.