Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/184.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在android中使用带正则表达式的SpannableString?_Java_Android_Regex - Fatal编程技术网

Java 如何在android中使用带正则表达式的SpannableString?

Java 如何在android中使用带正则表达式的SpannableString?,java,android,regex,Java,Android,Regex,我正在尝试使用以下函数在Android中使用spannableString和正则表达式为字符串的一部分着色: public static String StringReplace(String source) { String find = "ABC"; SpannableString replace = new SpannableString(find); replace.setSpan(new ForegroundColorSp

我正在尝试使用以下函数在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类测试扩展活动{
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String dispStr=“这里面有字符串ABCDEF\n这样做:ABCDEF-请参阅!\n然后再次单击此处”;
TextView tv=(TextView)findViewById(R.id.textView1);
tv.setText(dispStr);
更改文本视图(电视,“ABC”,颜色为红色);
}
私有void changeTextinView(文本视图电视、字符串目标、int颜色){
String vString=(String)tv.getText();
int startSpan=0,endSpan=0;
Spannable spanRange=新SpannableString(vString);
while(true){
startSpan=vString.indexOf(target,endSpan);
ForegroundColorSpan foreColour=新的ForegroundColorSpan(颜色);
//每个循环都需要一个新的跨度对象,否则它只会移动跨度
如果(起始跨距<0)
打破
endSpan=startSpan+target.length();
跨距范围。设置跨距(前幅、起始跨距、结束跨距、,
Spannable.SPAN_独占性SPAN_独占性);
}
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("<font color=\"red\">CBA</font>"));
textView.setText(modifiedText);
CharSequence modifiedText=replace.replace(“ABC aaa AB ABC aa ad ABC”,“ABC”,
fromHtml(“CBA”);
textView.setText(modifiedText);

这种方法非常好。但是,如果我想将其应用于字符串中的多个单词,该怎么办?编辑我的解决方案以更改目标字符串的所有出现情况,这也可以与“Html.fromHtml”一起使用吗?我的CustomTextView中的链接应该是可点击的。tv.setText(spanRange)不能用于我的案例。非常感谢。