我正在开发一个电子书应用程序,其中包含一些自定义标签,如 < 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 会删除标签
这里的问题是,您试图将
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());
如何将所有跨度包装在父级中,然后在扁平化文本上进行搜索:
final wrapper = TextSpan(children: spans);
final haystack = wrapper.toPlainText();