SpannableStringBuilder 用正则表达式替换内容

Posted

技术标签:

【中文标题】SpannableStringBuilder 用正则表达式替换内容【英文标题】:SpannableStringBuilder replace content with Regex 【发布时间】:2017-02-21 17:14:32 【问题描述】:

我有以下代码,我将在其中用SpannableString 标记大括号之间的内容并删除大括号,但它给出了错误的结果。

String text = "the quick brown fox jumps over the lazy dog. A Quick brownfoxjumpsoverthelazydog";

tv.setText(makeSpannable(text, "\\.*?\\"));
public SpannableStringBuilder makeSpannable(String text, String regex) 
    SpannableStringBuilder spannable = new SpannableStringBuilder(text);
    Pattern pattern = Pattern.compile(regex);
    Matcher matcher = pattern.matcher(spannable.toString());
    while (matcher.find()) 
        String word = matcher.group();
        String abbr = word.toString().substring(1, word.length() - 1);
        spannable.setSpan(new ForegroundColorSpan(Color.RED), matcher.start(), matcher.end(),  Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        spannable.replace(matcher.start(), matcher.start() + abbr.length() , abbr);
    
    return spannable;

输入:

the quick brown fox jumps over the lazy dog. A Quick brownfoxjumpsoverthelazydog

输出:

【问题讨论】:

【参考方案1】:

如果你不反对使用 html

tv.setText(Html.fromHtml(makeStringBuffer(text, regex, Color.RED).toString()));

private StringBuffer makeColoredStringBuffer(String text, String regex, int color) 
    // create a buffer to hold the replaced string
    StringBuffer sb = new StringBuffer();
    // create the pattern matcher
    Matcher m = Pattern.compile(regex).matcher(text);
    // iterate through all matches
    while (m.find()) 
        // get the match
        String word = m.group();
        // remove the first and last characters of the match and surround with html font tag
        String abbr = String.format("<font color='#%06X'>%s</font>", (0xFFFFFF & color), word.substring(1, word.length() - 1));
        // appendReplacement handles replacing within the current match's bounds
        m.appendReplacement(sb, abbr);
    
    // add any text left over after the final match
    m.appendTail(sb);
    return sb;

如果你想使用SpannableString

tv.setText(makeColoredSpannable(text, regex, Color.RED));

private SpannableStringBuilder makeColoredSpannable(String text, String regex, int color) 
    // create a spannable to hold the final result
    SpannableStringBuilder spannable = new SpannableStringBuilder();
    // create a buffer to hold the replaced string
    StringBuffer sb = new StringBuffer();
    // create the pattern matcher
    Matcher m = Pattern.compile(regex).matcher(text);
    // iterate through all matches
    while (m.find()) 
        // get the match
        String word = m.group();
        // remove the first and last characters of the match
        String abbr = word.substring(1, word.length() - 1);
        // clear the string buffer
        sb.setLength(0);
        // appendReplacement handles replacing within the current match's bounds
        m.appendReplacement(sb, abbr);
        // append the new colored section to the spannable
        spannable.append(sb);
        spannable.setSpan(new ForegroundColorSpan(color), spannable.length() - abbr.length(), spannable.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    
    // clear the string buffer
    sb.setLength(0);
    // add any text left over after the final match
    m.appendTail(sb);
    spannable.append(sb);
    return spannable;

【讨论】:

您的回答很有帮助,感谢您的帮助和时间,:-) 这不会与@Muhammad 的回答重复吗?【参考方案2】:
String text = "the quick brown fox jumps over the lazy dog. A Quick brownfoxjumpsoverthelazydog";

tv.setText(makeSpannable(text, "\\.*?\\"));

public SpannableStringBuilder makeSpannable(String text, String regex) 

    StringBuffer sb = new StringBuffer();
    SpannableStringBuilder spannable = new SpannableStringBuilder();

    Pattern pattern = Pattern.compile(regex);
    Matcher matcher = pattern.matcher(text);
    while (matcher.find()) 
        sb.setLength(0); // clear
        String group = matcher.group();
        // caution, this code assumes your regex has single char delimiters
        String spanText = group.substring(1, group.length() - 1);
        matcher.appendReplacement(sb, spanText);

        spannable.append(sb.toString());
        int start = spannable.length() - spanText.length();

        spannable.setSpan(new ForegroundColorSpan(Color.RED), start, spannable.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    
    sb.setLength(0);
    matcher.appendTail(sb);
    spannable.append(sb.toString());
    return spannable;

【讨论】:

感谢您的帮助和宝贵的时间,很好的解决方案,它的工作就像魅力。 :-) android 开发者:不要将android.os.Patternjava.util.regex.Pattern 混淆 @kris larson 如何替换 quick brow[n] fox 跳 over #l#azy 狗。 A Quick brown.如何使用不同的颜色标记它们并移除刹车?在这种情况下你能帮我吗? 这可能有助于解决您的用例:gist.github.com/nesquena/f2504c642c5de47b371278ee61c75124@ShahriarNasimNafi

以上是关于SpannableStringBuilder 用正则表达式替换内容的主要内容,如果未能解决你的问题,请参考以下文章

SpannableString与SpannableStringBuilder使用

SpannableString与SpannableStringBuilder使用

在 TextView 中使用 SpannableStringBuilder 的段落间距

使用 SpannableStringBuilder 时,为啥我的文本没有以样式显示?

SpannableStringBuilder 用正则表达式替换内容

SpannableStringBuilder