Android, SQLite и REGEXP

225
25 января 2018, 19:02

Здравствуйте.
Пишется Андроид-приложение, в нем требуется использование Базы данных и поиск по ней с использованием регулярных выражений. Веб-версия (реализация PHP+MySQL) и воспроизведение запросов в DB Browser for SQLite работают, но те же запросы с той же таблицей на Android выводят результат некорректно (код и результат прилагаются).

Вопрос: как привести эту идею (поиск совпадений такого рода в морфологическом словаре) в рабочее состояние (вижу решение этой проблемы только через регулярные выражения, но не буду против любых других рабочих предложений)?

Код:

package bot12313.datebasecheck;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
    static SQLiteDatabase mydatabase;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    @Override
    protected void onStart() {
        super.onStart();
        mydatabase = openOrCreateDatabase("test.db", MODE_PRIVATE, null);
        String tag = "Search";
        mydatabase.execSQL("DROP TABLE IF EXISTS `template`");
        mydatabase.execSQL("CREATE TABLE `template` ( `ID` INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE, `name` TEXT )");
        mydatabase.execSQL("INSERT INTO `template` VALUES (1,'слов(а|о|у|)')");
        mydatabase.execSQL("INSERT INTO `template` VALUES (2,'букв(а|ы|у|)')");
        String[] queries = new String[]{
                "SELECT * FROM template WHERE 'слово' REGEXP '(^| )'||template.name||'( |$)'",
                "SELECT * FROM template WHERE 'буква' REGEXP '(^| )'||template.name||'( |$)'",
                "SELECT * FROM template WHERE 'слово буква' REGEXP '(^| )'||template.name||'( |$)'"
        };
        for(String query : queries) {
            Cursor cur = mydatabase.rawQuery(query, null);
            Log.e(tag,query);
            if (cur != null) {
                Log.e(tag, "Result size = " + cur.getCount());
                if (cur.moveToFirst()) {
                    do {
                        for (int i = 0; i < cur.getColumnCount(); i++)
                            Log.e(tag, cur.getColumnName(i) + ": " + cur.getString(i));
                    } while (cur.moveToNext());
                }
                cur.close();
            }
            Log.e(tag,"_____");
        }
    }
}

И вырезка из Логов:

E/Search: SELECT * FROM template WHERE 'слово' REGEXP '(^| )'||template.name||'( |$)'
E/Search: Result size = 1
E/Search: ID: 1
E/Search: name: слов(а|о|у|)
E/Search: _____
E/Search: SELECT * FROM template WHERE 'буква' REGEXP '(^| )'||template.name||'( |$)'
E/Search: Result size = 1
E/Search: ID: 2
E/Search: name: букв(а|ы|у|)
E/Search: _____
E/Search: SELECT * FROM template WHERE 'слово буква' REGEXP '(^| )'||template.name||'( |$)'
E/Search: Result size = 0
E/Search: _____

UPD (где "некорректный результат"): Имеем следующую таблицу:

+----+--------------+
| ID | Name         |
+----+--------------+
| 1  | слов(а|о|у|) |
+----+--------------+
| 2  | букв(а|ы|у|) |
+----+--------------+

И следующие запросы:

 1. SELECT * FROM template WHERE 'слово' REGEXP '(^| )'||template.name||'( |$)'
 2. SELECT * FROM template WHERE 'буква' REGEXP '(^| )'||template.name||'( |$)'
 3. SELECT * FROM template WHERE 'слово буква' REGEXP '(^| )'||template.name||'( |$)'

Если перевести запросы на человеческий язык, то имеем:

  1. Найти строки, которые являются шаблоном для строки 'слово'
    На этот запрос мы имеем верный ответ: всего одна строка таблицы удовлетворяет запросу (строка с ID=1)
  2. Найти строки, которые являются шаблоном для строки 'буква'
    На этот запрос мы тоже имеем верный ответ: всего одна строка удовлетворяет запросу (строка с ID=2)
  3. Найти строки, которые являются шаблоном для строки 'слово буква'
    Здесь программа выдает неверный ответ, так как для этого запроса, обе строки таблицы будут шаблоном.
Answer 1

А вам не кажется, что запрос №3 неверно построен?

Я бы написал так:

SELECT * FROM template 
    WHERE 
      'слово' REGEXP '(^| )'||template.name||'( |$)'
      or
      'буква' REGEXP '(^| )'||template.name||'( |$)'
READ ALSO
Java pattern mapper

Java pattern mapper

Изучаю некоторые паттерны и вот остановился на паттерне мап

232
Задача про окончание урока [java] [требует правки]

Задача про окончание урока [java] [требует правки]

Подскажите пожалуйста как решать эту задачу на JavaПоявился предмет программирования и сходу на 2 паре дали эту задачу

208
Парсинг HTML на Java с Jsoup

Парсинг HTML на Java с Jsoup

Как можно получить 56,4115 вот отсюда:

245
Итератор Java в JavaScript

Итератор Java в JavaScript

Есть код на Java:

231