我有以下代码:
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
?
答案 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
循环中起作用。因此,我必须创建一个计数器来更新字符位置,删除字符后。这是必要的,因为Matcher
与content
变量相关联。因此,当它替换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;
}
无论如何,我不知道这是否是最佳方法。