Browse Source

Добавлен поиск по регулярным выражениям

Book Pauk 2 years ago
parent
commit
c17b696d61

+ 8 - 1
client/components/Search/BaseList.js

@@ -385,7 +385,14 @@ export default class BaseList {
             } else if (searchValue[0] == '#') {
 
                 searchValue = searchValue.substring(1);
-                return !bookValue || (bookValue !== emptyFieldValue && !enru.has(bookValue[0]) && bookValue.indexOf(searchValue) >= 0);
+                if (!bookValue)
+                    return false;
+                return bookValue !== emptyFieldValue && !enru.has(bookValue[0]) && bookValue.indexOf(searchValue) >= 0;
+            } else if (searchValue[0] == '~') {//RegExp
+
+                searchValue = searchValue.substring(1);
+                const re = new RegExp(searchValue, 'gi');
+                return re.exec(bookValue);
             } else {
                 //where = `@dirtyIndexLR('value', ${db.esc(a)}, ${db.esc(a + maxUtf8Char)})`;
                 return bookValue.localeCompare(searchValue) >= 0 && bookValue.localeCompare(searchValue + maxUtf8Char) <= 0;

+ 5 - 0
client/components/Search/Search.vue

@@ -789,6 +789,11 @@ class Search {
             Указание простого "#" в поиске по названию означает: найти всех авторов, названия книг которых начинаются не с русской или латинской буквы
         </li>
         <br>
+        <li>
+            "~" поиск по регулярному выражению. Например, для "~^\\s" в поле названия, будут найдены
+            все книги, названия которых начинаются с пробельного символа
+        </li>
+        <br>
         <li>
             "?" поиск пустых значений или тех, что начинаются с этого символа. Например, "?" в поле серии означает: найти всех авторов, у которых есть книги без серий
             или название серии начинается с "?".

+ 3 - 0
client/components/Search/SelectExtSearchDialog/SelectExtSearchDialog.vue

@@ -160,6 +160,9 @@ class SelectExtSearchDialog {
         <li>
             префикс "#": поиск подстроки в строке, но только среди начинающихся не с латинского или кириллического символа
         </li>
+        <li>
+            префикс "~": поиск по регулярному выражению
+        </li>
         <li>
             префикс "?": поиск пустых значений или тех, что начинаются с этого символа
         </li>

+ 24 - 5
server/core/DbSearcher.js

@@ -63,8 +63,18 @@ class DbSearcher {
             a = a.substring(1);
             where = `@indexIter('value', (v) => {
                 const enru = new Set(${db.esc(enruArr)});
-                return !v || (v !== ${db.esc(emptyFieldValue)} && !enru.has(v[0]) && v.indexOf(${db.esc(a)}) >= 0);
+                if (!v)
+                    return false;
+                return v !== ${db.esc(emptyFieldValue)} && !enru.has(v[0]) && v.indexOf(${db.esc(a)}) >= 0;
             })`;
+        } else if (a[0] == '~') {//RegExp
+            a = a.substring(1);
+            where = `
+                await (async() => {
+                    const re = new RegExp(${db.esc(a)}, 'gi');
+                    @@indexIter('value', (v) => re.exec(v) );
+                })()
+            `;
         } else {
             where = `@dirtyIndexLR('value', ${db.esc(a)}, ${db.esc(a + maxUtf8Char)})`;
         }
@@ -99,7 +109,7 @@ class DbSearcher {
         };
 
         //авторы
-        if (query.author && query.author !== '*') {
+        if (query.author) {
             const key = `book-ids-author-${query.author}`;
             let ids = await this.getCached(key);
 
@@ -113,7 +123,7 @@ class DbSearcher {
         }
 
         //серии
-        if (query.series && query.series !== '*') {
+        if (query.series) {
             const key = `book-ids-series-${query.series}`;
             let ids = await this.getCached(key);
 
@@ -127,7 +137,7 @@ class DbSearcher {
         }
 
         //названия
-        if (query.title && query.title !== '*') {
+        if (query.title) {
             const key = `book-ids-title-${query.title}`;
             let ids = await this.getCached(key);
 
@@ -337,7 +347,7 @@ class DbSearcher {
         //то в выборку по bookId могут попасть авторы, которые отсутствуют в критерии query.author,
         //поэтому дополнительно фильтруем
         let result = null;
-        if (from == 'author' && query.author && query.author !== '*') {
+        if (from == 'author' && query.author) {
             const key = `filter-ids-author-${query.author}`;
             let authorIds = await this.getCached(key);
 
@@ -562,6 +572,15 @@ class DbSearcher {
 
                     searchValue = searchValue.substring(1);
                     return `(row.${bookField} === '' || (!enru.has(row.${bookField}.toLowerCase()[0]) && row.${bookField}.toLowerCase().indexOf(${db.esc(searchValue)}) >= 0))`;
+                } else if (searchValue[0] == '~') {//RegExp
+                    searchValue = searchValue.substring(1);
+
+                    return `
+                        (() => {
+                            const re = new RegExp(${db.esc(searchValue)}, 'gi');
+                            return re.exec(row.${bookField});
+                        })()
+                    `;
                 } else {
 
                     return `(row.${bookField}.toLowerCase().localeCompare(${db.esc(searchValue)}) >= 0 ` +

+ 8 - 1
server/core/opds/BasePage.js

@@ -250,7 +250,14 @@ class BasePage {
             } else if (searchValue[0] == '#') {
 
                 searchValue = searchValue.substring(1);
-                return !bookValue || (bookValue !== emptyFieldValue && !enru.has(bookValue[0]) && bookValue.indexOf(searchValue) >= 0);
+                if (!bookValue)
+                    return false;
+                return bookValue !== emptyFieldValue && !enru.has(bookValue[0]) && bookValue.indexOf(searchValue) >= 0;
+            } else if (searchValue[0] == '~') {//RegExp
+
+                searchValue = searchValue.substring(1);
+                const re = new RegExp(searchValue, 'gi');
+                return re.exec(bookValue);
             } else {
                 //where = `@dirtyIndexLR('value', ${db.esc(a)}, ${db.esc(a + maxUtf8Char)})`;
                 return bookValue.localeCompare(searchValue) >= 0 && bookValue.localeCompare(searchValue + maxUtf8Char) <= 0;

+ 3 - 0
server/core/opds/SearchHelpPage.js

@@ -31,6 +31,9 @@ class SearchHelpPage extends BasePage {
     <li>
         префикс "#": поиск подстроки в строке, но только среди значений, начинающихся не с латинского или кириллического символа
     </li>
+    <li>
+        префикс "~": поиск по регулярному выражению
+    </li>
     <li>
         префикс "?": поиск пустых значений или тех, что начинаются с этого символа
     </li>