用没有 HTML 的 Span 替换某些字符串

问题描述

我正在尝试用跨度替换某个字符串。

例如我有这个字符串:

String s = "redHello greenWorld";

我想将“红色”替换为:

modifiedText.setSpan(new ForegroundColorSpan(Color.parseColor("#FF0000")),start,end,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

和“绿色”:

modifiedText.setSpan(new ForegroundColorSpan(Color.parseColor("#00FF00")),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

所以我以这种方式创建了 modifiedText:

Spannable modifiedText = new SpannableString(s);

如何在没有 HTML 的情况下用 Span 替换某个字符串?

解决方法

SpannableString 不会拆分(子字符串)给定的 String。它只是使用开始和结束索引更改给定范围的属性。如果要更改 String 某些部分的颜色,则不需要子字符串(或剪切)。只需对要更改的部分使用开始和结束索引,其余部分将保持不变(原始)。在您的情况下,根据您的问题,您想更改红色和绿色单词的颜色,因此只需使用 2 个 setSpan 方法,这些单词的开始和结束索引为。

String s = "redHello greenWorld";
SpannableString modifiedText = new SpannableString(s);

//Change the color for 'red' word
modifiedText.setSpan(new ForegroundColorSpan(Color.parseColor("#FF0000")),3,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

//Change the color for 'green' word
modifiedText.setSpan(new ForegroundColorSpan(Color.parseColor("#00FF00")),9,14,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

即使它是 SpannableString,它仍然是 String,因此如果您想为您的 String 设置为 Text,您可以像使用 View 一样使用它。例如,如果您想将该 String 设置为您的 TextView,请将 setText() 方法与您的 SpannableString 一起使用。

textView.setText(modifiedText);
,

既然你问了删减 - 我希望这就是你的意思(新代码)

//setup
String text = "redHello greenWorld redTest";
List<String> colors = new ArrayList<>();
colors.add("red");
colors.add("green");

//finding the positions
List<Integer> pos = new ArrayList<>();
List<String> colorPositions = new ArrayList<>();
for (String toFind: colors) {
    Pattern word = Pattern.compile(toFind);
    Matcher match = word.matcher(text);
    while (match.find()) {
       pos.add(match.start());
       colorPositions.add(toFind);
    }
}

//replacing
for (String element : colors) {
    text = text.replace(element,"");
}

现在你需要对列表进行排序

//really inefficient sorting
boolean sorted = false;
Integer temp_pos;
String temp_color;
Integer[] sorted_pos = pos.toArray(Integer[]::new);
String[] sorted_color = colorPositions.toArray(String[]::new);
while(!sorted) {
    sorted = true;
    for (int i = 0; i < sorted_pos.length - 1; i++) {
        if (sorted_pos[i] > sorted_pos[i + 1]) {
            temp_pos = sorted_pos[i];
            temp_color = sorted_color[i];
            sorted_pos[i] = sorted_pos[i + 1];
            sorted_color[i] = sorted_color[i + 1];
            sorted_pos[i + 1] = temp_pos;
            sorted_color[i + 1] = temp_color;
            sorted = false;
        }
    }
}

并减去“红色”和“绿色”

//subtracting
for (int i = 1; i < sorted_pos.length; i++) {
    for (int j = i; j < sorted_pos.length; j++) {
        sorted_pos[j] -= sorted_color[i - 1].length();
    }
}

最终结果现在包含 [0,6,12],即跨度的起始索引 - 现在您只需要遍历输出并设置跨度(跨度的颜色在 sorted_color 中)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...