Как вырезать часть строки до и после определённых символов
Никак не могу понять. Везде мануалы с индексом, но индекса мы не знаем, так как строки разной длины.
Пример: Есть URL адрес с метками, например https://start.spring.io/?utm_source=youtube&utm_medium=cpc&utm_campaign={campaignid}&utm_content={adgroupid}&utm_term={creative}
Задача получить значение находящееся между https://start.spring.io/?utm_source= и &utm_medium=cpc&utm_campaign={campaignid}&utm_content={adgroupid}&utm_term={creative}, то есть youtube и записать его в отдельную строку
Всё что нашёл - либо не работает, либо через регулярку, которую я не знаю, либо через индекс
Ответы (2 шт):
На самом деле вам нужно не просто получить часть строки, вам нужно парсить URL. Есть огромное количество готовых решений , но если вы хотите написать это самостоятельно, то метод будет выглядеть примерно так:
public static Map<String, String> splitQuery(URL url) throws UnsupportedEncodingException {
Map<String, String> queryParams = new LinkedHashMap<>();
for (String param : url.getQuery().split("&")) {
int idx = param.indexOf("=");
queryParams.put(URLDecoder.decode(param.substring(0, idx), "UTF-8"),
URLDecoder.decode(param.substring(idx + 1), "UTF-8"));
}
return queryParams;
}
Вызываете его , передавая new URL("...")(Вместо троеточия подсталяете свой url), получаете Map, содержащую все параметры запроса. По ключу дергаете нужный.
Что касается готовых решений, все зависит от того, что вы используете в своем проекте:
1)URLEncodedUtils for Apache http client or URLEncodedUtils for Apache http client 5
2)UriComponentsBuilder for Spring
3)HttpUrl for OkHttp
4)QueryStringDecoder for Netty
В своей практике больше не встречал, но уверен, что это далеко не исчерпывающий список. Выбирайте на свой вкус))
Для "простого" поиска в строке можно использовать перегруженный метод String::indexOf(String str) и String::indexOf(String str, int from), который впрочем зависит от регистра.
Также в общем случае может понадобиться декодировать значение параметра при помощи метода URLDecoder::decode
public static String getUrlParam(String url, String paramName) {
String param = paramName + "="; // включить знак = в имя параметра
int start = url.indexOf(param); // искать параметр
if (start == -1) return null; // параметр не найден
int end = url.indexOf("&", start += param.length()); // искать конец значения
if (end == -1) end = url.length(); // значение в конце входного УРЛа
try {
return URLDecoder.decode(url.substring(start, end), "UTF-8");
} catch (UnsupportedEncodingException unsencex) {
throw new RuntimeException(unsencex);
}
}
Аналогично можно искать при помощи регулярного выражения вида paramName + "=([^&]*)(&|$)", тогда будет несколько проще реализовать поиск независимый от регистра:
public static String getUrlParam(String url, String paramName) {
Pattern p = Pattern.compile(paramName + "=([^&]*)(&|$)", Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(url);
if (!m.find()) return null;
try {
return URLDecoder.decode(m.group(1), "UTF-8");
} catch (UnsupportedEncodingException unsencex) {
throw new RuntimeException(unsencex);
}
}
Смысл регулярки: после имени параметра и знака "равно" искать от 0 символов, не равных &, пока не будет найден разделитель параметров & или конец строки $.