Android中提取最后开始标签与对应首个结束标签间内容的技术问询
如何在Android中提取HTML里最后一个开始标签与对应首个结束标签的内容
嘿,我来帮你搞定这个Android开发里的HTML内容提取问题!你需要从给定的HTML结构中,抓取最后一个开始标签和它对应的第一个结束标签之间的完整内容(包括标签本身),就像示例里从<p><b><i><u>hello</u></i></b>prajakta</p>中提取出<u>hello</u>对吧?下面我给你两种实用的解决方案:
方案一:正则表达式快速实现(适合简单HTML场景)
如果你的HTML结构比较简单,没有复杂的标签属性或者嵌套异常,用正则表达式可以快速实现需求。
针对特定标签(比如<u>)的提取
如果你明确要提取的是某个特定标签(比如示例里的<u>),可以直接写精准的正则:
String htmlContent = "<p><b><i><u>hello</u></i></b>prajakta</p>"; // 匹配<u>和</u>之间的内容,非贪婪模式确保只取第一个闭合的标签 Pattern uTagPattern = Pattern.compile("<u>(.*?)</u>"); Matcher matcher = uTagPattern.matcher(htmlContent); if (matcher.find()) { // 拼接回完整的标签内容 String extractedResult = "<u>" + matcher.group(1) + "</u>"; Log.d("HTML_EXTRACT", extractedResult); // 输出:<u>hello</u> }
通用提取(适配任意最后一个开始标签)
如果需要适配任意最后一个开始标签(不管是<u>、<i>还是其他),可以用动态匹配标签名的正则:
String htmlContent = "<p><b><i><u>hello</u></i></b>prajakta</p>"; // .* 匹配前面所有内容,确保捕获最后一个开始标签;\\1 反向引用匹配对应的结束标签 Pattern generalPattern = Pattern.compile(".*<([a-z]+)>(.*?)</\\1>"); Matcher matcher = generalPattern.matcher(htmlContent); if (matcher.find()) { String tagName = matcher.group(1); String innerContent = matcher.group(2); String extractedResult = "<" + tagName + ">" + innerContent + "</" + tagName + ">"; Log.d("HTML_EXTRACT", extractedResult); // 输出:<u>hello</u> }
方案二:原生Html解析(适合复杂HTML场景)
正则表达式的局限性很明显——如果HTML标签带属性(比如<u class="underline">)、存在自闭合标签或者嵌套混乱,正则就会失效。这时候用Android原生的Html类结合自定义TagHandler是更可靠的选择:
String htmlContent = "<p><b><i><u>hello</u></i></b>prajakta</p>"; final String[] lastTagResult = new String[1]; final Stack<String> tagStack = new Stack<>(); // 跟踪标签嵌套顺序 Html.fromHtml(htmlContent, Html.FROM_HTML_MODE_LEGACY, null, new Html.TagHandler() { @Override public void handleTag(boolean isOpeningTag, String tagName, Editable output, XMLReader xmlReader) { if (isOpeningTag) { // 记录开始标签,同时在当前位置标记一个占位Span tagStack.push(tagName); output.setSpan(new Object(), output.length(), output.length(), Spanned.SPAN_MARK_MARK); } else { // 处理结束标签时,匹配对应的开始标签 if (!tagStack.isEmpty() && tagStack.peek().equals(tagName)) { tagStack.pop(); // 找到之前标记的占位Span,确定开始位置 Object[] spans = output.getSpans(0, output.length(), Object.class); for (Object span : spans) { int startPos = output.getSpanStart(span); int endPos = output.getSpanEnd(span); if (startPos == endPos && endPos == output.length()) { // 拼接完整的标签内容 String innerText = output.subSequence(startPos, output.length()).toString(); lastTagResult[0] = "<" + tagName + ">" + innerText + "</" + tagName + ">"; output.removeSpan(span); break; } } } } } }); Log.d("HTML_EXTRACT", lastTagResult[0]); // 输出:<u>hello</u>
注意事项
- 正则方案适合结构简单、标签规范的HTML,开发速度快但容错性差;
- 原生解析方案适配复杂HTML场景,容错性强,代码稍复杂但稳定性更高;
- 如果你的项目允许引入第三方库,也可以考虑用Jsoup来解析HTML,它的API更友好,处理复杂HTML更得心应手。
内容的提问来源于stack exchange,提问作者PrajaktaParkhade
相关产品推荐
相关产品推荐

