Сохранение Regex в виде строк в базе данных и последующее извлечение для использования в Javascript и PHP - PullRequest
1 голос
/ 01 августа 2020

Основной вопрос: Должны ли экранированные обратные косые черты также храниться в базе данных для Javascript и насколько хорошо это будет работать с механизмом регулярных выражений PHP?

Подробности

У меня есть несколько шаблонов регулярных выражений, которые можно использовать для классификации строк по различным категориям. Пример приведен ниже:

(^A)|(\(A)

Это может распознать, например, « A » в начале строки или если он находится сразу после открытия скобка (, но не если это где-то еще в строке.

  • DB C ( A B C) AA

  • A B C (DB C) AA

Мой проект использует эти шаблоны регулярных выражений на двух языках PHP и Javascript.

Я хочу сохранить эти шаблоны в базе данных MySQL, и, поскольку нет типа данных для регулярного выражения, я подумал, что могу сохранить его как VARCHAR или TEXT.

Проблема возникает, если я напрямую использую строки в Javascript, \( считается только как (, поскольку \ backsla sh используется как escape-символ. если это используется для создания new RegExp, это дает ошибку:

Uncaught SyntaxError: незавершенная скобка

Например:

let regexstring = "(^A)|(\(A)";

console.log(regexstring); // outputs => "(^A)|((A)"

let regex = new RegExp(regexstring); // Gives Uncaught SyntaxError: unterminated parenthetical

На основе на этот ответ в StackOverflow, решение состоит в том, чтобы избежать обратных косых черт, например:

let regexstring = "(^A)|(\\(A)";

console.log(regexstring); // Outputs => "(^A)|(\\(A)"

regex = new RegExp(regexstring);

Таким образом, вопрос состоит в том, что экранированные обратные косые черты также должны храниться в базе данных и насколько хорошо это будет работать с движком регулярных выражений PHP?

1 Ответ

2 голосов
/ 01 августа 2020

Я бы сохранил необработанное регулярное выражение.

Дополнительный escape-символ на самом деле не является частью регулярного выражения. Он нужен JS для правильной обработки строки, потому что \ имеет особое значение. Вам нужно указать его при записи строки как «жестко запрограммированного» текста. Фактически, он также понадобится на стороне PHP, если бы вы использовали ту же технику присваивания в PHP, вы бы написали его с escape-backsla sh:

$regexstring = "(^A)|(\\(A)";

Вы также можете избавиться от него, если изменили способ инициализации regexstring в своем JS:

<?
...
$regexstring = $results[0]["regexstring"];
?>

let regexstring = decodeURIComponent("<?=rawurlencode($regexstring);?>");
console.log(regexstring);

Другой вариант - просто добавить экранирующие обратные косые черты на стороне PHP:

<?
...
$regexstring = $results[0]["regexstring"];
$escapedRegexstring = str_replace('\', '\\', $regexstring);
?>

let regexstring = "<?=$escapedRegexstring;?>";

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

Наконец, если эти регулярные выражения предназначены для предоставления пользователями, имейте в виду, что вывод их как есть в код JS очень опасен, поскольку может легко вызвать XSS-уязвимость. Первый способ - пропустить через rawurlencode (со стороны PHP) и decodeURIComponent (со стороны JS) - должен устранить этот риск.

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