在flutter中突出显示InlineSpans的某些部分

问题描述 投票:0回答:2

我正在开发一个电子书应用程序,其中包含一些自定义标签,如 < t >、< nm >、< ar >、< bs >、< mean > 以及这些用 < t >

包裹的标签

我的文字如下;

< t > < title >İkinci Lem’a< /title >< t > < bs > ﷽ < /bs >< t > < ar >اِذْ نَادٰي رَبَّهُٓ اَنّ۪ى مَسَّنِىَ الضُّرُّ وَاَنْتَ اَرْحَمُ الرَّاحِم۪ينَ< /ar >< t > < t ><nm>1</nm><t>\nSabır kahramanı Hazret-i Eyyub Aleyhisselâmın şu < t >< mean >münâcât< /mean >< t >ı, hem < t >< mean >mücerreb< /mean >< t >, hem tesirlidir. <t><nm>2</nm><t>Fakat ayetten <t><mean>iktibas</mean><t> <mean>suret</mean><t>inde, bizler, <t><mean>münâcât</mean><t >ımızda\t\t\t\t < t >< ar >رَبّ۪ى اِنّ۪ى مَسَّنِىَ الضُّرُّ وَاَنْتَ اَرْحَمُ الرَّاحِم۪ينَ< / ar>

我用标签分割文本,并根据相应的标签创建文本或小部件范围。然后我想突出显示一些文本,而不关心数据的范围或文本样式。我尝试了很多方法但都无法成功。

我尝试分割将突出显示的参考词,但没有成功。 我拆分了单词并检查了参考字符串是否包含。这给出了部分解决方案,但它也突出显示了文本的不同部分,这并不是为了突出显示。

我的参考字符串是:

String tt = "Hazret-i Eyyub Aleyhisselâmın meşhur kıssasının hülâsası şudur ki: \nPek çok yara bere içinde epey müddet kaldığı halde, o hastalığın azîm mükâfatını düşünerek, kemal-i sabırla tahammül edip kalmış.";

当我运行时,它看起来像这样:

我只希望字符串等于参考字符串具有背景颜色。

这个函数是我分割字符串并创建跨度列表的地方

List<InlineSpan> getText(String t,) {
v = t.removeTags();

    List<InlineSpan> spans = [];

    List<String> words = t.split("<t>");

    for (var word in words) {
      if (isImage(word)) {
        spans.add(imageSpan(word,));
      } else if (isTitle(word).$1) {
        spans.add(titleSpan(word));
      } else if (hasMeaning(word)) {
        spans.add(meaningsSpan(word));
      } else if (isSn(word)) {
        spans.add(snSpan(word));
      } else if (isBesmele(word)) {
        spans.add(besmeleSpan(word));
      } else if (isYildiz(word)) {
        spans.add(yildizSpan(word));
      } else if (isNumber(word)) {
        spans.add(ayetNumberSpan(word));
      } else if (isHasiye(word)) {
        spans.add(hasiyeSpan(word));
      } else if (isArabic(word)) {
        spans.add(arapcaSpan(word));
      } else {
  
        spans.add(textSpan(word, word, null, null));
      }
    }

    return spans;
  }

这是根据标签单词组成返回自定义样式的textSpan

TextSpan textSpan(String text, String word, double? height, Function(TapUpDetails)? onTapUp) {

    final list = text.split(" ");
    final length = list.length;
    return   TextSpan(
      children: list.mapIndexed((index, e){
var s = "";

if(index ==0){
 s = e;
}else if(index>0&& index==length){
  s = "${text.split(" ")[index - 1]??""} $e ";
}else if(index>0&& index<length-1){
  s = "${text.split(" ")[index - 1]??""} $e ${text.split(" ")[index +1]??""}";
}else if(index<length-1){
  s = "${text.split(" ")[index - 1]??""} $e ${text.split(" ")[index +1]??""}";
}

        return TextSpan(
         text: e + " ",
        style: TextStyle(
            color: getColor(word),
            fontSize: getFontSize(word),
            fontFamily: getFont(word),
            fontWeight: getFontWeight(word),
            fontStyle: getFontStyle(word),
            backgroundColor:  commentColor(s ),
            height: height),
            recognizer: TapGestureRecognizer()..onTapUp = onTapUp);
     
      } ).toList()
      
 
       );

  }

我尝试分割跨度文本,并尝试查看每个单词的前一个单词或下一个单词,并尝试在参考字符串中找到完全匹配。但没有成功

这是我尝试为文本样式添加突出显示颜色的功能

Color? commentColor(String s){

    RegExp exp =  RegExp( "\\b$s\\b", caseSensitive: false, ); 
    bool contains = exp.hasMatch(tt);
  
    if(contains){
    return Colors.cyan;
  }

  return null;
} 

任何IDE都会被应用。

注意:当我在没有空格的情况下编写标签时,stackoverflow 会删除标签

flutter dart highlight textspan
2个回答
0
投票

这里的问题是,您试图将

multi-line string
与旨在匹配
regular expression
single word
模式相匹配。正则表达式中的
\\b
单词边界锚点意味着
match the boundaries of a single word
,而不是
multi-line string
。并且一定已经在这里见过

commentColor
函数中,您使用
RegExp
模式
\\b($s)\\b
,它尝试将整个字符串
tt
作为字符串
s
中的单个单词进行匹配。由于
tt
包含换行符并且跨越多行,因此不符合单词边界条件。

所以如果你想检查

tt
是否出现在字符串
s
中的任何位置,你可以简单地使用
contains
方法而不使用正则表达式:

Color? commentColor(String s) {
  bool contains = s.contains(tt);

  if (contains) {
    return Colors.cyan;
  }else{
    return null;
  }
}

对于不区分大小写的搜索,只需替换行:

bool contains = s.toLowerCase().contains(tt.toLowerCase());

0
投票

如何将所有跨度包装在父级中,然后在扁平化文本上进行搜索

final wrapper = TextSpan(children: spans);
final haystack = wrapper.toPlainText();
© www.soinside.com 2019 - 2024. All rights reserved.