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

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

String text = "the {quic}k brown {fox} jumps {over} the lazy dog. {A Quick} {brow}nfoxjumpsoverthelazydog";

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 {quic}k brown {fox} jumps {over} the lazy dog. {A Quick} {brow}nfoxjumpsoverthelazydog

输出:

【问题讨论】:

    标签: java android regex spannablestring spannablestringbuilder


    【解决方案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 {quic}k brown {fox} jumps {over} the lazy dog. {A Quick} {brow}nfoxjumpsoverthelazydog";
    
    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 如何替换 {quic}k brow[n] {fox} 跳 {over} #l#azy 狗。 {A Quick} {brow}n.如何使用不同的颜色标记它们并移除刹车?在这种情况下你能帮我吗?
    • 这可能有助于解决您的用例:gist.github.com/nesquena/f2504c642c5de47b371278ee61c75124@ShahriarNasimNafi
    猜你喜欢
    • 2016-04-06
    • 1970-01-01
    • 2018-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-04
    • 2019-07-25
    • 2019-01-27
    相关资源
    最近更新 更多