Вы можете решить обе задачи, используя регулярные выражения.Но для второй задачи (извлечение цены из HTML) вы можете использовать JSOUP , который гораздо лучше подходит для извлечения контента из HTML.
Вот несколько возможных решений на основе регулярных выраженийдля ваших задач:
1.Изменить URL
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*["'](?<price>.+?)["']
) для определения цены. С именованной группой ((?<price>.+?)
) вы можете затем извлечь цену.
Я возвращаю 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
Upдата 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);
}