私がしたいこと...Android用JSoupより優れているものは何ですか?
私はアンドロイドアプリでwebviewを持っています。私はアプリケーションのユーザー(アンドロイドの電話ユーザー)からの文字列と検索文字列として、サーバーから巨大なhtmlコンテンツを取得します。今度は検索文字列を壊して正規表現を作成します。 WebViewに表示すると、正規表現に一致するすべてのhtmlコンテンツが強調表示されます。それはhtmlですので、私は正規表現をラップしたい私は何をしようとした...
は、黄色の背景とタグのペアに言葉を一致しました。
- 私が得るhtmlコンテンツのシンプルなregexとreplaceAll。 '<'と '>'の内部にあるものであっても、ネジを入れて交換するので間違っています。
- MatcherとPatternのコンボを使ってみました。タグ内の内容を省略することは困難です。
- 私はJSOUPパーサーを使いました。
私は、NodeTraversorクラスを使用してhtmlをトラバースします。私はMatcherとPatternクラスを使って、一致した単語を検索し、タグで置き換えました。
しかし、それは非常に遅いです。そして、私は基本的にそれをAndroidで使用したいと思っています。サイズは284kBです。私は不要なクラスをいくつか削除しましたが、今は201kBですが、まだアンドロイドデバイスにとってはあまりにも多いです。さらに、htmlコンテンツは非常に大きくなる可能性があります。 JSoupのソースも調べました。それはパースするときに、すべての単一の文字を繰り返し処理します。私はすべてのパーサーが同じように動作するかどうかはわかりませんが、大規模なhtmlドキュメントでは間違いなく遅いです。ここで
は私のコードです -
htmlString = getHtmlFromServer();
Highlighter hl = new Highlighter("Hello World!", htmlString);
new htmlString = hl.getHighlightedHTML();
私は私がやっていることは最も最適な方法ではありません確信している - ここで
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
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;
}
}
}
は、私はそれを呼び出す方法です。しかし、私は他の何かを考えるように見えることはできません。
私は にしたい - それを強調するのにかかる時間を減らす。 - ライブラリのサイズを小さくする
何か提案がありますか?
を参照してください。 – Enigma