【问题标题】:subtract part of text减去部分文本
【发布时间】:2018-10-06 19:04:04
【问题描述】:

我有这个代码

public void descargarURL() {
    try{
        URL url = new URL("https://www.amazon.es/MSI-Titan-GT73EVR-7RD-1027XES-Ordenador/dp/B078ZYX4R5/ref=sr_1_1?ie=UTF8&qid=1524239679&sr=8-1");
        BufferedReader lectura = new BufferedReader(new InputStreamReader(url.openStream()));
        File archivo = new File("descarga2.txt");
        BufferedWriter escritura = new BufferedWriter(new FileWriter(archivo));
        BufferedWriter ficheroNuevo = new BufferedWriter(new FileWriter("nuevoFichero.txt"));
        String texto;

        while ((texto = lectura.readLine()) != null) {
            escritura.write(texto);

            }
        lectura.close();
        escritura.close();
        ficheroNuevo.close();
        System.out.println("Archivo creado!");
        //}

    }
    catch(Exception ex) {
        ex.printStackTrace();
    }
}
public static void main(String[] args) throws FileNotFoundException, IOException {
    Paginaweb2 pg = new Paginaweb2();
    pg.descargarURL();
}

}

我想从 URL 中删除 B078ZYX4R5 的引用部分,以及这个实体 /

在文本文件中保存的html之后,有一部分代码有*"<div id =" cerberus-data-metrics "style =" display: none; "data-asin =" B078ZYX4R5 "data-as-price = "1479.00" data-asin-shipping = "0" data-asin-currency-code = "EUR" data-substitute-count = "0" data-device-type = "WEB" data-display-code = "Asin is not eligible because it has a retail offer "> </ div>"*,我只想从那里得到1479.00的价格,它被包含在内在标签 "data-as-price = "

我不想使用外部库,我知道可以用split、index of和substring来完成

谢谢!!!!

【问题讨论】:

标签: java split substring indexof


【解决方案1】:

您可以使用正则表达式解决这两个任务。然而对于第二个任务(从 HTML 中提取价格),您可以使用JSOUP,它更适合从 HTML 中提取内容。

以下是一些基于正则表达式的可能解决方案:

1。更改网址

private static String modifyUrl(String str) {
    return str.replaceFirst("/[^/]+(?=/ref)", "");
}

这只是使用正则表达式的替换,使用正向预测(?=/ref)(请参阅https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html

提取价格

private static Optional<String> extractPrice(String html) {
    Pattern pat = Pattern.compile("data-as-price\\s*=\\s*[\"'](?<price>.+?)[\"']", Pattern.MULTILINE);
    Matcher m = pat.matcher(html);
    if(m.find()) {
        String price = m.group("price");
        return Optional.of(price);
    }
    return Optional.empty();
}

您还可以在此处使用正则表达式 (data-as-price\s*=\s*["'](?&lt;price&gt;.+?)["']) 来定位价格。然后,您可以使用命名组 ((?&lt;price&gt;.+?)) 提取价格。

我在这里返回一个Optional,以便您处理找不到价格的情况。

以下是两种方法的简单测试用例:

public static void main(String[] args) throws IOException {
    String str = "https://www.amazon.es/MSI-Titan-GT73EVR-7RD-1027XES-Ordenador/dp/B078ZYX4R5/ref=sr_1_1?ie=UTF8&qid=1524239679&sr=8-1";
    System.out.println(modifyUrl(str));
    String html = "<div id =\" cerberus-data-metrics \"style =\" display: none; \"data-asin =\" B078ZYX4R5 \"data-as-price = \"1479.00\" data-asin-shipping = \"0\" data-asin-currency-code = \"EUR\" data-substitute-count = \"0\" data-device-type = \"WEB\" data-display-code = \"Asin is not eligible because it has a retail offer \"> </ div>";
    extractPrice(html).ifPresent(System.out::println);
}

如果你运行这个简单的测试用例,你会在控制台上看到这个输出:

https://www.amazon.es/MSI-Titan-GT73EVR-7RD-1027XES-Ordenador/dp/ref=sr_1_1?ie=UTF8&qid=1524239679&sr=8-1
1479.00

更新

如果您想从 URL 中提取参考,您可以使用与用于提取价格的代码类似的代码来完成。这是一种从模式中提取特定命名组的方法:

private static Optional<String> extractNamedGroup(String str, Pattern pat, String reference) {
    Matcher m = pat.matcher(str);
    if (m.find()) {
        return Optional.of(m.group(reference));
    }
    return Optional.empty();
}

那么你就可以用这个方法来提取参考和价格了:

private static Optional<String> extractReference(String str) {
    Pattern pat = Pattern.compile("/(?<reference>[^/]+)(?=/ref)");
    return extractNamedGroup(str, pat, "reference");
}

private static Optional<String> extractPrice(String html) {
    Pattern pat = Pattern.compile("data-as-price\\s*=\\s*[\"'](?<price>.+?)[\"']", Pattern.MULTILINE);
    return extractNamedGroup(html, pat, "price");
}

您可以使用以下方法测试上述方法:

public static void main(String[] args) throws IOException {
    String str = "https://www.amazon.es/MSI-Titan-GT73EVR-7RD-1027XES-Ordenador/dp/B078ZYX4R5/ref=sr_1_1?ie=UTF8&qid=1524239679&sr=8-1";
    extractReference(str).ifPresent(System.out::println);
    String html = "<div id =\" cerberus-data-metrics \"style =\" display: none; \"data-asin =\" B078ZYX4R5 \"data-as-price = \"1479.00\" data-asin-shipping = \"0\" data-asin-currency-code = \"EUR\" data-substitute-count = \"0\" data-device-type = \"WEB\" data-display-code = \"Asin is not eligible because it has a retail offer \"> </ div>";
    extractPrice(html).ifPresent(System.out::println);
}

这将打印:

B078ZYX4R5
1479.00

更新 2:使用 URL

如果您想使用java.net.URL 类来帮助您缩小搜索范围,您可以这样做。但是您不能使用此类进行完全提取。 由于您要提取的令牌位于 URL 路径中,因此您可以提取路径,然后应用上述正则表达式进行提取。

以下是可用于缩小搜索范围的示例代码:

public static void main(String[] args) throws IOException {
    String str = "https://www.amazon.es/MSI-Titan-GT73EVR-7RD-1027XES-Ordenador/dp/B078ZYX4R5/ref=sr_1_1?ie=UTF8&qid=1524239679&sr=8-1";
    URL url = new URL(str); 
    extractReference(url.getPath() /* narrowing the search scope here */).ifPresent(System.out::println);
    String html = "<div id =\" cerberus-data-metrics \"style =\" display: none; \"data-asin =\" B078ZYX4R5 \"data-as-price = \"1479.00\" data-asin-shipping = \"0\" data-asin-currency-code = \"EUR\" data-substitute-count = \"0\" data-device-type = \"WEB\" data-display-code = \"Asin is not eligible because it has a retail offer \"> </ div>";
    extractPrice(html).ifPresent(System.out::println);
}

【讨论】:

  • 太棒了,非常感谢,但是没有其他方法可以将 URL 传递给 String 而不将其设置为默认值吗?然后在console出来的,价格不错,但是网址,我只想要B078ZYX4R5的参考,非常感谢!
  • @Ashe 请检查更新的答案,其中包含提取参考的方法。
  • 但是如果不将其设置为默认值,是否有另一种方法可以将 URL 传递给 String?
  • @Ashe 实际上,我对“另一种将 URL 传递给 String 而不将其设置为默认值的方法”的含义并没有 100% 的理解。我假设您想使用 java.net.URL 类的方法来执行某种提取,而不是使用纯输入字符串。请确认我的假设是否正确。
  • 对了,我想用URL类的方法,所以在做function函数的时候,你不要离开我,建议?
猜你喜欢
  • 2018-10-05
  • 2014-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多