【问题标题】:Get text between two tags using substringBetween() method of StringUtils使用 StringUtils 的 substringBetween() 方法获取两个标签之间的文本
【发布时间】:2018-10-23 07:39:32
【问题描述】:

我有这样的输入:

<address>
    <addressLine>280 Flinders Mall</addressLine>
    <geoCodeGranularity>PROPERTY</geoCodeGranularity>
</address>
<address type="office">
    <addressLine>IT Park</addressLine>
    <geoCodeGranularity>office Space</geoCodeGranularity>
</address>

我想捕获地址标签之间的所有内容。

我试过了:

File file = new File("test.html");
String testHtml = FileUtils.readFileToString(file); 
String title = StringUtils.substringBetween(testHtml, "<address>", "</address>");

这并不适用于所有情况,因为地址标签内部可能包含一些属性。请帮助如何获取此类字符串的文本。

【问题讨论】:

  • 您应该在这里使用 XPath 解析器,而不是使用字符串或正则表达式库。
  • 文件太大,由于性能问题,我无法使用 Parser。所以,我尝试使用像 StringUtils 这样的正则表达式或 Java 库。
  • 您的预期输出是什么样的,它是什么?它是文件、字符串还是其他东西?
  • 最终目标是获取地址标签之间所有字符的计数。所以我试图从 StringUtils 获取字符串输出,然后找到它的计数。如果我走错了路,请纠正我。我知道 Parser 是实现这一目标的最佳方法。但由于性能问题,我不允许使用解析器。
  • 所以你想要一个 single 数字,用于 any &lt;address&gt; 标签之间的 all 个字符的计数?对吗?

标签: java apache-stringutils


【解决方案1】:

一般而言,您应该使用正则表达式来解析 HTML/XML 内容。相反,请使用 XPath 之类的解析器。鉴于您似乎无法使用解析器,我们可以使用模式匹配器尝试以下选项:

int count = 0;
String input = "<address>\n<addressLine>280 Flinders Mall</addressLine>\n    <geoCodeGranularity>PROPERTY</geoCodeGranularity>\n</address>\n<address type=\"office\">\n    <addressLine>IT Park</addressLine>\n    <geoCodeGranularity>office Space</geoCodeGranularity>\n</address>";
String pattern = "<address[^>]*>(.*?)</address>";
Pattern r = Pattern.compile(pattern, Pattern.DOTALL);
Matcher m = r.matcher(input);

while (m.find( )) {
    count += m.group(1).length();
    System.out.println("Found value: " + m.group(1) );
}

System.out.println("count = " + count);  

这将为您的示例数据中的两个 &lt;address&gt; 标记找到 198 个计数。

要使用BufferedReader 进行这项工作,您可能必须确保一次读取一个完整的&lt;address&gt; 标记。

【讨论】:

  • 您好,感谢您的回答。正如您在答案中所写的,这适用于单个输入字符串。但是,当我尝试通过缓冲区阅读器读取输入文件时,这不起作用。
  • 一次读入一个&lt;address&gt;标签。然后使用我的答案,滚动剩余内容以捕获下一个&lt;address&gt; 标签。
  • 很抱歉,我没有理解您的最后回复。我对 java I/O 很陌生。
  • 如果问题是我的答案只有在你有一个带有完整 &lt;address&gt; 标签和结束标签的字符串时才有效,那么解决方案是继续阅读,直到找到一个开始和结束标签。所以你必须做一些解析工作。
  • 是否可以在 java 中一次读取一个
    标签?我知道我们可以使用 BufferedReader 和 readLine() 逐行读取整个文件。
【解决方案2】:

您可以将文件转换为字符串,并可以确定所需子字符串的开始和结束索引,如下所示:

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

public class Address {

    public static void main(String[] args) throws IOException {

        // Complete File Path
        File dir =
            new File("\\..\\..\\Test.html");

        // Convert File Data As String
        String data =
            new String(
                Files.readAllBytes(Paths
                    .get(dir
                        .getAbsolutePath())));

        // For Loop to get all the <address> tags in the file.
        for (int index = data.indexOf("<address"); index >= 0;) {

            // Start Index
            int startIndex = data.indexOf(">", index + 1);
            ++startIndex;

            // End Index
            int indexOfEnd = data.indexOf("</address>", startIndex + 1);

            String attributesString = data.substring(startIndex, indexOfEnd);
            // Replace below line with desired logic with calling trim() on the String attributesString
            System.out.println(attributesString);

            // Next Address will be after the end of first address
            index = data.indexOf("<address", indexOfEnd + 1);
        }
    }
}

【讨论】:

  • 感谢您的回答。但我的文件大小是 102 MB。将文件数据转换为单个字符串是个好主意吗?
  • 执行频率是多少?
  • 一天执行一次。
  • 那么我相信这样做是可以的,只要你退出,Java GC 方法就会处理它。但也请考虑stackoverflow.com/questions/1179983/… 的帖子。
  • 我收到此错误 - 线程“main”java.lang.OutOfMemoryError 中的异常:Java 堆空间
【解决方案3】:
while (scan.hasNextLine()) {

        parser = scan.nextLine();
        // System.out.println(parser);
        if (parser.equals("<adress>")) {
            parser = scan.nextLine();
            // System.out.println(parser);
            int startPosition = parser.indexOf("<adressLine>") + "<adressLine>".length();
            int endPosition = parser.indexOf("</adressLine>", startPosition);
            idNumber = parser.substring(startPosition, endPosition);
            parser = scan.nextLine();

            int startPosition1 = parser.indexOf("<geoCodeGranularity>") + "<geoCodeGranularity>".length();
            int endPosition1 = parser.indexOf("</geoCodeGranularity>", startPosition1);
            time = parser.substring(startPosition1, endPosition1);
            parser = scan.nextLine();

…… 算法一定是这样的。如果您阅读了文件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-09
    • 2016-12-28
    • 1970-01-01
    • 2011-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多