Почему не жадное регулярное выражение терпит неудачу в Sqlite? - PullRequest
0 голосов
/ 08 ноября 2019

ниже двух запросов. Вторая группа в первом запросе жадная, в последнем нет.

Почему первая работает, а вторая нет?

SELECT * FROM table WHERE field REGEXP '(Color|Material)=(\w.*)($|,)';
SELECT * FROM table WHERE field REGEXP '(Color|Material)=(\w.*?)($|,)';

РЕДАКТИРОВАТЬ (в ответ на комментарии)

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

Вот вывод команды, показанный браузером БД для SQLite:

Result: invalid operand
At line 1:
SELECT * FROM table WHERE field REGEXP '(Color|Material)=(\w.*?)($|,)';

1 Ответ

1 голос
/ 09 ноября 2019

Как уже указывалось, sqlite не реализует свой собственный механизм регулярных выражений. (См. Раздел под названием Операторы LIKE, GLOB, REGEXP и MATCH в онлайновых документах .) Вместо этого поддержка регулярных выражений должна осуществляться программным обеспечением хоста. Таким образом, чтобы понять, какой синтаксис регулярного выражения поддерживается, требуется знание библиотеки, используемой таким программным обеспечением хоста.

Страница документов на веб-сайте браузера БД имеет Регулярные выражения запись. На этой странице упоминается, что DB Browser использует библиотеку регулярных выражений Qt, а эта страница документа Qt 5.0 , в свою очередь, говорит, что

реализует Perl-совместимые регулярные выражения.

Имеется ссылка на справочную страницу pcrepattern (3) со списком поддерживаемых операторов / синтаксиса.

На этой странице перечислены жадные и ленивые квантификаторы...

QUANTIFIERS

     ?           0 or 1, greedy
     ?+          0 or 1, possessive
     ??          0 or 1, lazy
     *           0 or more, greedy
     *+          0 or more, possessive
     *?          0 or more, lazy
     +           1 or more, greedy
     ++          1 or more, possessive
     +?          1 or more, lazy
     {n}         exactly n
     {n,m}       at least n, no more than m, greedy
     {n,m}+      at least n, no more than m, possessive
     {n,m}?      at least n, no more than m, lazy
     {n,}        n or more, greedy
     {n,}+       n or more, possessive
     {n,}?       n or more, lazy

Несмотря на утверждение, что Qt поддерживает Perl-совместимый синтаксис, ошибка указывает на то, что ленивый синтаксис фактически не поддерживается, поэтому мы возвращаемся к Qt 4.8 docs , который не содержит никаких ленивых конструкций. Однако на той же странице есть утверждение о не жадных (то есть ленивых) квантификаторах. Вот что он говорит:

Квантификаторы QRegExp такие же, как жадные квантификаторы Perl (но см. Примечание выше). Нежадное сопоставление не может применяться к отдельным квантификаторам, но может применяться ко всем квантификаторам в шаблоне. Например, для соответствия регулярному выражению Perl ro +? M требуется:

QRegExp rx("ro+m");
rx.setMinimal(true);

Хотя казалось, что мы приближаемся к возможному решению, нельзя вызвать какой-либо специальный метод Qt дляреализовать не жадные квантификаторы из оператора SQL, так что это был в основном тупик. Если мы вернемся к справочной странице pcrepattern (3) , мы увидим, что фактический синтаксис регулярного выражения в Perl поддерживает настройки встроенных параметров, более конкретно, параметр (?U), который устанавливает значение по умолчанию для квантификатора ungreedy (lazy). Вы можете попробовать поставить эту опцию в начале, но я почти уверен, что она не будет работать, так как вышеупомянутое исследование уже доказало, что Qt (и аналогично DB Browser) не поддерживает полный синтаксис Perl regex.

Окончательный вывод заключается просто в том, что не жадный синтаксис не поддерживается в DB Browser для sqlite. (не работает ли он? Не обязательно, скорее просто то, что конкретная конструкция не поддерживается .)Но помните, что эта конкретная реализация регулярного выражения имеет отношение только к браузеру БД. Если вы программируете sqlite на любой другой платформе, у вас может быть возможность включить другую реализацию REGEXP. Но это также не совсем так, потому что это зависит от того, какой язык и библиотеку sqlite вы используете.

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