Search code examples
regexflutterdartarabic

Search Arabic word with accent marks/diacritics


I have a JSON file which contains Arabic words with accent marks /diacritics,

I'm trying to search with normal Arabic words without marks then highlight the searched word with an accent

EX: User search with 'صلوات' without any accent will return "صَّلَوَاتِ" so I can highlight it

عَلَى أَنْ تَعْبُدُوا اللَّهَ وَلَا تُشْرِكُوا بِهِ شَيْئًا، وَالصَّلَوَاتِ الْخَمْسِ، وَأَسَرَّ كَلِمَةً خَفِيَّةً أَنْ لَا تَسْأَلُوا النَّاسَ شَيْئًا

will get

عَلَى أَنْ تَعْبُدُوا اللَّهَ وَلَا تُشْرِكُوا بِهِ شَيْئًا، وَالصَّلَوَاتِ الْخَمْسِ، وَأَسَرَّ كَلِمَةً خَفِيَّةً أَنْ لَا تَسْأَلُوا النَّاسَ شَيْئًا


Search Method used on textformfield

List<Hades> hadesList = [];            \\json file list 
List<Hades> searchHadesList = [];      

Future<void> searchHadesText(String text) {
    searchHadesList = hadesList
        .where((element) => RemoveExtinctionsAtWord()
            .normalise(element.hades)
            .contains(RemoveExtinctionsAtWord().normalise(text)))
        .toList();
  }

in this code, I have to remove both diacritics from the searched text and the JSON file in order to compare between them


Solution

  • You can add optional diacritic mark pattern after each char:

    var output = text.replaceAllMapped(RegExp(word.split("").join("\\p{M}*"), caseSensitive: false, unicode: true), (Match m) => "<span>${m[0]}</span>")
    

    Notes:

    • \p{M} - matches any diacritic mark
    • unicode: true enables the use of Unicode property classes like \p{M} in the pattern
    • .replaceAllMapped is required since the match value should be used in the replacement