首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java 字符串中查找單詞位置並高亮:indexOf 循環與 SpannableStringBuilder 實現

     編輯:程式設計綜合問答

需求分析

給定長文本與單詞數組,查找每個單詞在文本中的所有出現位置 (start, end),並用 `SpannableStringBuilder` 高亮顯示 (Android TextView)。

核心算法:遍歷查找

public static List findAllOccurrences(String text, String word) {
    List positions = new ArrayList<>();
    if (text == null || word == null || word.isEmpty()) return positions;
    
    int index = 0;
    while ((index = text.indexOf(word, index)) != -1) {
        positions.add(new int[]{index, index + word.length()});
        index += word.length(); // 移動到下一個可能位置,避免重疊匹配
    }
    return positions;
}

完整高亮實現 (Android)

public static SpannableStringBuilder highlightKeywords(Context context, String text, String[] keywords, int highlightColor) {
    SpannableStringBuilder ssb = new SpannableStringBuilder(text);
    for (String keyword : keywords) {
        if (TextUtils.isEmpty(keyword)) continue;
        List positions = findAllOccurrences(text, keyword);
        for (int[] pos : positions) {
            // 設置前景色高亮
            ssb.setSpan(new ForegroundColorSpan(highlightColor), pos[0], pos[1], Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            // 可選:背景色、粗體、點擊事件
            // ssb.setSpan(new BackgroundColorSpan(Color.YELLOW), pos[0], pos[1], Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            // ssb.setSpan(new StyleSpan(Typeface.BOLD), pos[0], pos[1], Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            // ssb.setSpan(new ClickableSpan() { ... }, pos[0], pos[1], Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
    }
    return ssb;
}

// 使用
TextView textView = findViewById(R.id.tv);
textView.setText(highlightKeywords(this, longText, new String[]{"關鍵詞1", "關鍵詞2"}, Color.RED));
textView.setMovementMethod(LinkMovementMethod.getInstance()); // 若包含 ClickableSpan

優化建議

  1. Trie 樹 / Aho-Corasick 自動機:單詞數組大 (>100) 時,構建 AC 自動機單次掃描文本 O(n + m + z),避免多次 `indexOf` O(k * n)。
  2. 正則表達式:`Pattern.compile("\\b(" + TextUtils.join("|", keywords) + ")\\b")` 邊界匹配,但需轉義特殊字符,性能略低於 AC 自動機。
  3. 大小寫不敏感:文本與關鍵詞統一 `toLowerCase()` 索引,但高亮需用原文位置,需維護映射表。

參考資源

結束位置 = 開始位置 + 關鍵詞長度 (`word.length()`),注意 `Spanned.SPAN_EXCLUSIVE_EXCLUSIVE` 標誌決定插入字符時區間擴展行為。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved