Android:突出显示SpannableString中的<em>标记

时间:2016-12-09 15:11:38

标签: java android spannablestring

我有以下代码:

public static SpannableString getSpannable ( String content )
{
    SpannableString s = new SpannableString ( content );

    Matcher m = Pattern.compile ( "<em>(.*?)</em>" ).matcher ( content );

    while ( m.find () )
    { s.setSpan ( new BackgroundColorSpan ( R.color.colorItalic ), m.start ( 1 ), m.end ( 1 ), 0 ); }

    return s;
}

它获取所有<em>(.*?)</em>并将BackgroundColorSpan设置为您的相应位置的第一组(.*?)

效果很好!但问题是<em>也在字符串内容中......在设置所有范围后,如何从<em>删除SpannableString

2 个答案:

答案 0 :(得分:2)

而不是SpannableStringBuilder使用replace并使用String content = "Yeah, <em>This</em> is bold."; SpannableStringBuilder s = new SpannableStringBuilder(content); String startTag = "<em>"; int startTagLength = startTag.length(); String endTag = "</em>"; int endTagLength = endTag.length(); Matcher m = Pattern.compile(startTag + "(.*?)" + endTag).matcher(content); while (m.find()) { Log.e(TAG, "" + m.start(1)); Log.e(TAG, "" + m.end(1)); s.setSpan(new BackgroundColorSpan(R.color.red), m.start(1), m.end(1), 0); s.replace(m.end(1), m.end(1) + endTagLength, ""); s.replace(m.start(1) - startTagLength, m.start(1), ""); } TextView out = (TextView) findViewById(R.id.out); out.setText(s); 方法。

试试这段代码,

TreeMap

修改

Caique Monteiro Araujo在评论中提到它不适用于多个标签。原因是因为我在while循环中替换了字符串,所以字符串长度在第二次迭代中变得混乱。

我很高兴Caique Monteiro Araujo找到了解决方法。以下是我的。我使用String content = "<em>This</em> is <em>bold</em>."; SpannableStringBuilder s = new SpannableStringBuilder(content); String startTag = "<em>"; int startTagLength = startTag.length(); String endTag = "</em>"; int endTagLength = endTag.length(); Matcher m = Pattern.compile(startTag + "(.*?)" + endTag).matcher(content); // TreeMap to store the start and end pair TreeMap<Integer, Integer> pair = new TreeMap<>(); while (m.find()) { // Store the start and end pair.put(m.start(1), m.end(1)); s.setSpan(new BackgroundColorSpan(R.color.red), m.start(1), m.end(1), 0); } // Use descendingMap to reverse the Map NavigableMap<Integer, Integer> reversePair = pair.descendingMap(); // Replace the tags starting from the last occurrence to avoid messing the length for (Integer key : reversePair.keySet()) { Integer end = reversePair.get(key); s.replace(end, end + endTagLength, ""); s.replace(key - startTagLength, key, ""); } TextView out = (TextView) findViewById(R.id.out); out.setText(s); 来存储(开始,结束)对并在另一个循环中替换标记。我不知道这是否有点矫枉过正。

'LINEINDEX'

答案 1 :(得分:0)

我使用@K Neeraj Lal帮助找到了解决方案,我非常感激。关键是,他的回答并没有在while循环中起作用。因此,我必须创建一个计数器来更新字符位置,删除字符后。这是必要的,因为Matchercontent变量相关联。因此,当它替换s变量时,它会改变您的长度,但内容变量仍具有相同的长度(Matcher链接到的位置)。解决方案代码是:

public static SpannableStringBuilder getSpannable ( String content )
{
    SpannableStringBuilder s = new SpannableStringBuilder ( content );

    String startAt = "<em>";
    String endAt   = "</em>";

    Matcher m = Pattern.compile ( startAt + "(.*?)" + endAt ).matcher ( content );

    int counter = 0, length  = startAt.length() + endAt.length();
    int startA, startB, endA, endB;

    while ( m.find () )
    {
        startA = m.start()-counter;
        endA   = m.end(1)-counter;
        startB = m.start(1)-counter;
        endB   = m.end()-counter;

        s.setSpan ( new BackgroundColorSpan ( R.color.colorItalic ), startB, endA, 0 );
        s.replace ( endA, endB, "" );
        s.replace ( startA, startB, "" );

        counter += length;
    }

    return s;
}

无论如何,我不知道这是否是最佳方法。