【问题标题】:How to use SpannableString with Regex in android?如何在 android 中使用 SpannableString 和正则表达式?
【发布时间】:2011-11-13 21:56:55
【问题描述】:

我正在尝试使用此函数在 Android 中使用 spannableString 和正则表达式为字符串的一部分着色:

public static String StringReplace(String source) {
        String find = "ABC";
        SpannableString replace = new SpannableString(find);        
        replace.setSpan(new ForegroundColorSpan(Color.RED), 0, 1, Spannable.SPAN_INCLUSIVE_INCLUSIVE);

        String output = source.replace(find, replace);
        return  output;
    }

因为函数 replace() 返回一个字符串,所以我无法获得彩色字符串。我的问题是:使用正则表达式为部分文本着色的最佳方法是什么?

【问题讨论】:

    标签: java android regex


    【解决方案1】:

    9 月 10 日更新 - 更改所有出现的目标字符串

    这样的通用方法会起作用:

    public class SpanTest extends Activity {
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            String dispStr = "This has the string ABCDEF in it \nSo does this :ABCDEF - see!\nAnd again ABCD here";
            TextView tv = (TextView) findViewById(R.id.textView1);
            tv.setText(dispStr);
            changeTextinView(tv, "ABC", Color.RED);
        }
    
        private void changeTextinView(TextView tv, String target, int colour) {
            String vString = (String) tv.getText();
            int startSpan = 0, endSpan = 0;
            Spannable spanRange = new SpannableString(vString);
    
            while (true) {
                startSpan = vString.indexOf(target, endSpan);
                ForegroundColorSpan foreColour = new ForegroundColorSpan(colour);
                // Need a NEW span object every loop, else it just moves the span
                if (startSpan < 0)
                    break;
                endSpan = startSpan + target.length();
                spanRange.setSpan(foreColour, startSpan, endSpan,
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
            tv.setText(spanRange);
        }
    
    }
    

    .

    【讨论】:

    • 这个方法很不错。但是如果我想将它应用于字符串中的多个单词怎么办?
    • 编辑了我的解决方案以更改所有出现的目标字符串
    • 这个也可以和“Html.fromHtml”一起使用吗?我的 CustomTextView 中的链接应该是可点击的。 tv.setText(spanRange) 在我的情况下不能使用。谢谢。
    【解决方案2】:

    这是一个可以帮助你的课程:

    public class Replacer {
        private final CharSequence mSource;
        private final CharSequence mReplacement;
        private final Matcher mMatcher;
        private int mAppendPosition;
        private final boolean mIsSpannable;
    
        public static CharSequence replace(CharSequence source, String regex,
                CharSequence replacement) {
    
            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(source);
            return new Replacer(source, matcher, replacement).doReplace();
        }
    
        private Replacer(CharSequence source, Matcher matcher,
                CharSequence replacement) {
            mSource = source;
            mReplacement = replacement;
            mMatcher = matcher;
            mAppendPosition = 0;
            mIsSpannable = replacement instanceof Spannable;
        }
    
        private CharSequence doReplace() {
            SpannableStringBuilder buffer = new SpannableStringBuilder();
            while (mMatcher.find()) {
                appendReplacement(buffer);
            }
            return appendTail(buffer);
        }
    
        private void appendReplacement(SpannableStringBuilder buffer) {
            buffer.append(mSource.subSequence(mAppendPosition, mMatcher.start()));
            CharSequence replacement = mIsSpannable
                    ? copyCharSequenceWithSpans(mReplacement)
                    : mReplacement;
            buffer.append(replacement);
    
            mAppendPosition = mMatcher.end();
        }
    
        public SpannableStringBuilder appendTail(SpannableStringBuilder buffer) {
            buffer.append(mSource.subSequence(mAppendPosition, mSource.length()));
            return buffer;
        }
    
        // This is a weird way of copying spans, but I don't know any better way.
        private CharSequence copyCharSequenceWithSpans(CharSequence string) {
            Parcel parcel = Parcel.obtain();
            try {
                TextUtils.writeToParcel(string, parcel, 0);
                parcel.setDataPosition(0);
                return TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
            } finally {
                parcel.recycle();
            }
        }
    }
    

    还有一个用法示例:

    CharSequence modifiedText = Replacer.replace("ABC aaa AB ABC aa ad ABC", "ABC",
        Html.fromHtml("<font color=\"red\">CBA</font>"));
    textView.setText(modifiedText);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-06
      • 2017-01-18
      • 2020-09-14
      • 1970-01-01
      • 2020-02-12
      • 2021-11-29
      • 2012-04-07
      相关资源
      最近更新 更多