在SQLite中搜索时排除HTML标记和一些UNICODE字符

时间:2017-02-06 07:52:36

标签: android regex c++11

更新#4

我已成功运行firstchar示例,但现在问题在于使用regex。即使在包含头文件之后,它也无法识别regex运算符。有什么线索可以解决这个问题吗?

更新#2

我已经在我的项目中编译了sqlite3库。我现在正在寻找任何人帮我编写regex函数,将其附加到数据库并从查询中调用它。

更新#3

我已经从this示例中编写了一些代码。这是

extern "C"
void
Java_com_kfmwa916_testapp_DatabaseHandler_createFunction() {
    sqlite3 *db;
    //Open database
    sqlite3_open("MyDBName.db", &db);

    //Attach function to database
    sqlite3_create_function(db, "firstchar", 1, SQLITE_UTF8, NULL, &firstchar, NULL, NULL);
}

firstchar函数是,

static void firstchar(sqlite3_context *context, int argc, sqlite3_value **argv) {
    if (argc == 1) {
        char *text = (char *) sqlite3_value_text(argv[0]);
        if (text && text[0]) {
            char result[2];
            result[0] = text[0]; result[1] = '\0';
            sqlite3_result_text(context, result, -1, SQLITE_TRANSIENT);
            return;
        }
    }
    sqlite3_result_null(context);
}

并在我的查询中使用它,如

SELECT firstchar(text) FROM dummy

但是它给出了错误

no such function firstchar()

非常感谢任何帮助。

原始问题

我正在使用在SQLite中以UNICODE格式保存的阿拉伯语。我想实现搜索。但这是一个问题。

让我们说文字是



<html>
  <head>
    <style>
      @font-face {
        font-family: "Al_Mushaf";
        src: url('fonts/al_mushaf.ttf');
      }
      @font-face {
        font-family: "Jameel Noori Nastaleeq";
        src: url('fonts/jameel_noori.ttf');
      }
    </style>
  </head>
  
  <body>
    <h3 style='font-family:"Al_Mushaf"'>
            صحابہ کرام کا انبیائے کرام کی سنّت پر عمل
            میٹھے میٹھے اسلامی بھائیو!صدائے مدینہ لگانا انبیائے کِرام عَلَیْہِمُ السَّلَام کی اس قَدْر پیاری سنّت ہے کہ صحابۂ کِرام عَلَیْہِمُ الرِّضْوَان نے بھی اسے خُوب اپنایا اور وہ بھی حضرت سَیِّدُنا داؤد عَلَیْہِ السَّلَام کی طرح اپنے گھر والوں کو جگایا کرتے جیسا کہ حضرت سَیِّدُنا عبد اللہ بن عُمَر رَضِیَاللّٰہُ تَعَالٰی عَنْہُما فرماتے ہیں کہ میرے والِدِ مُحْتَرَم اَمِیرُ الْمُوْمِنِین حضرت سَیِّدُنا عُمَر فَارُوقِ اَعْظَم رَضِیَاللّٰہُ تَعَالٰی عَنْہ رات میں جس قَدْر ربّ تعالیٰ چاہتا،نَماز پڑھتے رہتے،یہاں تک کہ جب رات کا آخری وَقْت ہوتا تو اپنے گھر والوں کو بھی نَماز کے لیے جگا دیتے اور ان سے فرماتے: اَلصَّلٰوة یعنی نماز۔ پھر یہ آیت مُبارَکہ تِلاوَت فرماتے:
            وَاۡمُرْ اَہۡلَکَ بِالصَّلٰوۃِ وَ اصْطَبِرْ عَلَیۡہَا ؕ لَا نَسْـَٔلُکَ رِزْقًا ؕ نَحْنُ نَرْزُقُکَ ؕ وَالْعٰقِبَۃُ لِلتَّقْوٰی (پ۱۶،طٰهٰ:۱۳۲)
    </h3>
  </body>
  
</html>
&#13;
&#13;
&#13;

它存储在SQLite数据库中。现在我要搜索html,它会返回结果,如果我搜索مبارکہ,它就不会返回结果,因为在实际文本中,它是مُبارَکہ(这些额外的UNICODE)。

我想在搜索时忽略所有HTML标记和这些额外的UNICODE字符,以便htmlمبارکہ返回结果时不应返回结果。

到目前为止我发现了什么;

  1. 制作额外的列并将删除的文本放入其中然后搜索(我无法执行此操作,因为有数千本书会占用大量内存)

  2. UDF Like SQL(我无法找到任何合适的示例/教程来实现它)

  3. 使用REGEXP(我无法弄清楚如何做到这一点,我只知道我自己实现了它)

  4. 使用LIKE和GLOB运算符和通配符进行SQL查询。

  5. 我被困了两天,找不到合适的解决方案。选项#4是可取的,但任何有效的解决方案都将具有魅力。

    与此同时,我还要保持应用程序内存的有效性并优化搜索。

    非常感谢任何帮助。

    更新

    我已使正则表达式忽略样式标记之间的html标记和文本,并在REGEXP的查询中使用它。

    现在有两个问题,

    1. 我也想忽略这些额外的字符。我知道他们的UNICODE,只需要知道如何在正则表达式中添加它。这是我的正则表达式;

      (?![^<]*>)(?!<style[^>]*?>)(TEXT)(?![^<]*?<\/style>)

    2. 我在

      等查询中使用过它

      SELECT text FROM dummy WHERE text REGEXP <myregex>

      它没有给出错误但也没有返回所需的结果。

1 个答案:

答案 0 :(得分:4)

回答原始问题

注意:正如我最近学到的那样,我在很多地方可能都错了,请纠正我的错误

有两种解决方案

  1. 使用function dataService($http) { var data = { UserLogin: UserLogin } return data; function UserLogin() { //whatever } } 运算符和SQLite查询
  2. 使用NDK实现您自己的用户定义函数
  3. 第一个问题是它返回REGEXPtrue,但我需要数据。这两种方法的问题在于您必须在Android项目中使用C / C ++库。所以我决定创建自己的用户定义函数。

    您可以在项目中找到有关如何使用NDK的许多教程,但在项目中找不到任何使用第三方库的完整示例。

    经过大量的搜索/学习,我结合了许多不同的地方,完成了我的任务。以下是有关如何执行此操作的一些步骤。我还打算写一个完整的分步教程。

    做好准备

    1. 首先,您需要在项目中使用的库。就我而言,我需要false合并的库,可以从here下载。将它们解压缩到项目的sqlite3文件夹中。
    2. 当您在项目中包含NDK时,您可能已经熟悉cpp文件了。是时候在CMakeLists.txt文件中添加这些库了。为此,转到CMakeLists.txt窗格,您会在其中看到Project,在其中您将看到所需的文件。打开它并按如下方式编辑,
    3. External Build Files

      您必须先使用# Sets the minimum version of CMake required to build the native # library. You should either keep the default value or only pass a # value of 3.4.0 or lower. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") cmake_minimum_required(VERSION 3.4.1) # Creates and names a library, sets it as either STATIC # or SHARED, and provides the relative paths to its source code. # You can define multiple libraries, and CMake builds it for you. # Gradle automatically packages shared libraries with your APK. add_library( # Sets the name of the library. native-lib # Sets the library as a shared library. SHARED # Provides a relative path to your source file(s). # Associated headers in the same location as their source # file are automatically included. src/main/cpp/native-lib.cpp ) include_directories(${CMAKE_SOURCE_DIR}/src) add_library(sqlite3 STATIC src/main/cpp/sqlite3.c src/main/cpp/sqlite3.h src/main/cpp/sqlite3ext.h) add_executable(sqlite src/main/cpp/sqlite3.c src/main/cpp/sqlite3.h src/main/cpp/sqlite3ext.h) set_target_properties(sqlite PROPERTIES OUTPUT_NAME sqlite3) # Searches for a specified prebuilt library and stores the path as a # variable. Because system libraries are included in the search path by # default, you only need to specify the name of the public NDK library # you want to add. CMake verifies that the library exists before # completing its build. find_library( # Sets the name of the path variable. log-lib # Specifies the name of the NDK library that # you want CMake to locate. log ) # Specifies libraries CMake should link to your target library. You # can link multiple libraries, such as libraries you define in the # build script, prebuilt third-party libraries, or system libraries. target_link_libraries( # Specifies the target library. native-lib # Links the target library to the log library # included in the NDK. sqlite3 log )添加库,然后将其链接到您所创建的类,默认情况下名为add_library

      1. 建立你的项目,你准备好了。
      2. 实施功能

        现在是主要部分。打开native-lib.cpp并添加必需的native-lib.cppfiles。你需要做什么;

        1. 制作一个您将从headers拨打电话的功能。一看到文件,就会知道模式。在我的情况下,它是YourActivity.java其中
        2. Java_com_kfmwa916_testapp_SearchResult_createFunction(JNIEnv * env, jobject object, jstring search)是关键字

          Java是你的包裹

          com_kfmwa916_testapp是您的SearchResult班级

          Java是函数的名称。

          1. 创建您的功能。就我而言,我必须在搜索中应用某些createFunction。这是我的,

            regex
          2. 创建static void strip_text(sqlite3_context *context, int argc, sqlite3_value **argv) { if(argc == 1) { __android_log_print(ANDROID_LOG_VERBOSE, "TAG", "inside strip_text"); char *result = (char *) sqlite3_value_text(argv[0]); std::string text(result); std::regex regex_head("YOUR REGEX"); if (!text.empty()) { text = std::regex_replace(text, regex_head, ""); sqlite3_result_text(context, text.c_str(), -1, SQLITE_TRANSIENT); __android_log_print(ANDROID_LOG_VERBOSE, "STRIPPED TEXT", "%s", text.c_str()); return; } } sqlite3_result_null(context); } 实例,打开数据库,将此函数附加到数据库并在查询中使用它。这是一段代码片段

            sqlite3
          3. 实施extern "C" void Java_com_kfmwa916_testapp_SearchResult_createFunction(JNIEnv * env, jobject object, jstring search) { const char * search_term = env->GetStringUTFChars(search, 0); env->ReleaseStringUTFChars(search, search_term); std::string q(search_term); std::string query = "SELECT text FROM dummy WHERE LIKE('%" + q + "%', strip_text(text))=1"; __android_log_print(ANDROID_LOG_VERBOSE, "TAG", "%s", query.c_str()); //GetJStringContent(env, search, search_term); sqlite3 *db; //Open database __android_log_print(ANDROID_LOG_VERBOSE, "TAG", "Opening database"); int rc = sqlite3_open("/data/data/com.kfmwa916.testapp/databases/MyDBName.db", &db); //It'll be good to check 'rc' for error(s). //Attach function to database __android_log_print(ANDROID_LOG_VERBOSE, "TAG", "Attaching function"); rc = sqlite3_create_function(db, "strip_text", 1, SQLITE_ANY, NULL, &strip_text, NULL, NULL); __android_log_print(ANDROID_LOG_VERBOSE, "TAG", "Executing query"); rc = sqlite3_exec(db, query.c_str(), callback, NULL, NULL); } 函数来处理结果。它应该看起来像

            callback
          4. 最后来到你的static int callback(void *NotUsed, int argc, char **argv, char **azColName) { __android_log_print(ANDROID_LOG_VERBOSE, "TAG", "FOUND"); int i; for (i = 0; i < argc; ++i) { __android_log_print(ANDROID_LOG_VERBOSE, "TAG", "%s = %sn", azColName[i], argv[i] ? argv[i] : "NULL"); } return 0; } 班,就我而言,它是Java加载库和定义函数。

            SearchResult
          5. 并将其调用到您想要的位置。让我们说static { System.loadLibrary("native-lib"); } public native void createFunction(String search);

            之类的按钮onClickEvent

            发布帖子可以进行更正和修改。