如何在android中使用带有Regex的SpannableString?

我正在尝试使用此函数在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()返回一个字符串,我无法获得彩色字符串。 我的问题是:使用regexp为文本部分着色的最佳方法是什么?

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); } } 

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

 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("CBA")); textView.setText(modifiedText);