2011-12-07 1 views
1

私はJSoupパーサを使ってhtml文書の特定の部分(regexで定義されている部分)を見つけ出し、見つかった文字列を<span>タグで囲んで強調表示しています。JSOUPでandroid用にRegexを使ってハイライトする

public String highlightRegex() { 
Document doc = Jsoup.parse(htmlContent); 

     NodeTraversor nd = new NodeTraversor(new NodeVisitor() { 

      @Override 
      public void tail(Node node, int depth) { 
       if (node instanceof Element) { 

        Element elem = (Element) node; 

        StringBuffer obtainedText; 
        for(Element tn : elem.getElementsMatchingOwnText(pat)) { 

         Log.e("HELLO", tn.baseUri()); 
         Log.e("HELLO", tn.text()); 
         obtainedText = new StringBuffer(tn.ownText()); 
         mat = pat.matcher(obtainedText.toString()); 
         int nextStart = 0; 
         while(mat.find(nextStart)) { 
          obtainedText = obtainedText.replace(mat.start(), mat.end(), "<span>" + mat.group() + "</span>"); 
          nextStart = mat.end() + 1; 
         } 
         tn.text(obtainedText.toString()); 
         Log.e("HELLO" , "AFTER:" + tn.text()); 

        } 
       } 
      } 

      @Override 
      public void head(Node node, int depth) {   
      } 
     }); 

     nd.traverse(doc.body()); 
     return doc.toString(); 
    } 

それが作業を行いますが、タグ<span>は、WebViewの内部に表示されている - ここで強調表示を行い、私のコードです。私は間違って何をしていますか?

答えて

0

誰も知らないように見えます。ここで私が思いついたコードがあります。ゆっくりと非効率ですが、とにかく動作します。提案は受け入れられます:)

このクラスは、正規表現を使用して任意のHTMLを強調表示するために使用できます。これは、正規表現(abc)|(def)*に一致するすべてのものをハイライト表示されます

Highlighter hl = new Highlighter("abc def", htmlString); 
String newhtmlString = hl.getHighlightedHtml(); 

-

public class Highlighter { 

    private String regex; 
    private String htmlContent; 
    Pattern pat; 
    Matcher mat; 


    public Highlighter(String searchString, String htmlString) { 
     regex = buildRegexFromQuery(searchString); 
     htmlContent = htmlString; 
     pat = Pattern.compile(regex, Pattern.CASE_INSENSITIVE); 
    } 

    public String getHighlightedHtml() { 

     Document doc = Jsoup.parse(htmlContent); 

     final List<TextNode> nodesToChange = new ArrayList<TextNode>(); 

     NodeTraversor nd = new NodeTraversor(new NodeVisitor() { 

      @Override 
      public void tail(Node node, int depth) { 
       if (node instanceof TextNode) { 
        TextNode textNode = (TextNode) node; 
        String text = textNode.getWholeText(); 

        mat = pat.matcher(text); 

        if(mat.find()) { 
         nodesToChange.add(textNode); 
        } 
       } 
      } 

      @Override 
      public void head(Node node, int depth) {   
      } 
     }); 

     nd.traverse(doc.body()); 

     for (TextNode textNode : nodesToChange) { 
      Node newNode = buildElementForText(textNode); 
      textNode.replaceWith(newNode); 
     } 
     return doc.toString(); 
    } 

    private static String buildRegexFromQuery(String queryString) { 
     String regex = ""; 
     String queryToConvert = queryString; 

     /* Clean up query */ 

     queryToConvert = queryToConvert.replaceAll("[\\p{Punct}]*", " "); 
     queryToConvert = queryToConvert.replaceAll("[\\s]*", " "); 

     String[] regexArray = queryString.split(" "); 

     regex = "("; 
     for(int i = 0; i < regexArray.length - 1; i++) { 
      String item = regexArray[i]; 
      regex += "(\\b)" + item + "(\\b)|"; 
     } 

     regex += "(\\b)" + regexArray[regexArray.length - 1] + "[a-zA-Z0-9]*?(\\b))"; 
     return regex; 
    } 

    private Node buildElementForText(TextNode textNode) { 
     String text = textNode.getWholeText().trim(); 

     ArrayList<MatchedWord> matchedWordSet = new ArrayList<MatchedWord>(); 

     mat = pat.matcher(text); 

     while(mat.find()) { 
      matchedWordSet.add(new MatchedWord(mat.start(), mat.end())); 
     } 

     StringBuffer newText = new StringBuffer(text); 

     for(int i = matchedWordSet.size() - 1; i >= 0; i--) { 
      String wordToReplace = newText.substring(matchedWordSet.get(i).start, matchedWordSet.get(i).end); 
      wordToReplace = "<b>" + wordToReplace+ "</b>"; 
      newText = newText.replace(matchedWordSet.get(i).start, matchedWordSet.get(i).end, wordToReplace);  
     } 
     return new DataNode(newText.toString(), textNode.baseUri()); 
    } 

    class MatchedWord { 
     public int start; 
     public int end; 

     public MatchedWord(int start, int end) { 
      this.start = start; 
      this.end = end; 
     } 
    } 
} 

あなたが強調表示されたHTMLを取得するために、これらの2つのメソッドを呼び出す必要があります。 modifying buildRegexFromQuery()関数によって、正規表現の作成方法を変更することができます。

関連する問題