2011-09-09 1 views
4

私はこの機能を使ってAndroidの中でspannableStringと正規表現を使用して文字列の色の部分にしようとしています:機能置き換える()は文字列を返すアンドロイドのRegexで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; 
    } 

ので、私はない色の文字列を取得することができています。私の質問です:regexpを使用してテキストの一部を色付けする最良の方法は何ですか?

答えて

8

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

} 

を。ここで

+0

この方法は非常にいいです。しかし、もし私が文字列の中のいくつかの単語のためにそれを適用したいのですが? –

+0

私のソリューションを編集して、ターゲット文字列のすべての出現を変更してください – NickT

+0

ありがとうございます。非常に便利なコード –

4

がお手伝いしますクラスです。

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); 
関連する問題