У меня есть вход String как:
String text = "Some content which contains link as <A HREF=\"/relative-path/fruit.cgi?param1=abc&param2=xyz\">URL Label</A> and some text after it";
Я хочу преобразовать этот текст в:
Some content which contains link as http://www.google.com/relative-path/fruit.cgi?param1=abc¶m2=xyz&myParam=pqr (URL Label) and some text after it
Так вот:
1) Я хочу заменить тег ссылки простой ссылкой. Если тег содержит метку, он должен быть заключен в фигурные скобки после URL-адреса.
2) Если URL-адрес относительный, я хочу поставить префикс базового URL-адреса (http://www.google.com).
3) Я хочу добавить параметр к URL-адресу. (& myParam = pqr)
У меня проблемы с получением тега с URL и меткой и его заменой.
Я написал что-то вроде:
public static void main(String[] args) {
String text = "String text = "Some content which contains link as <A HREF=\"/relative-path/fruit.cgi?param1=abc&param2=xyz\">URL Label</A> and some text after it";";
text = text.replaceAll("<", "<");
text = text.replaceAll(">", ">");
text = text.replaceAll("&", "&");
// this is not working
Pattern p = Pattern.compile("href=\"(.*?)\"");
Matcher m = p.matcher(text);
String url = null;
if (m.find()) {
url = m.group(1);
}
}
// helper method to append new query params once I have the url
public static URI appendQueryParams(String uriToUpdate, String queryParamsToAppend) throws URISyntaxException {
URI oldUri = new URI(uriToUpdate);
String newQueryParams = oldUri.getQuery();
if (newQueryParams == null) {
newQueryParams = queryParamsToAppend;
} else {
newQueryParams += "&" + queryParamsToAppend;
}
URI newUri = new URI(oldUri.getScheme(), oldUri.getAuthority(),
oldUri.getPath(), newQueryParams, oldUri.getFragment());
return newUri;
}
Edit1:
Pattern p = Pattern.compile("HREF=\"(.*?)\"");
Это работает. Но тогда я хочу, чтобы он не зависел от капитализации. Href, HRef, href, hrEF и т.д. - все должно работать.
Кроме того, что делать, если в моем тексте несколько URL-адресов.
Edit2:
Некоторый прогресс.
Pattern p = Pattern.compile("href=\"(.*?)\"");
Matcher m = p.matcher(text);
String url = null;
while (m.find()) {
url = m.group(1);
System.out.println(url);
}
Это обрабатывает случай нескольких URL-адресов.
Последняя нерешенная проблема: как получить метку и заменить теги href в исходном тексте на URL и метку.
Edit3:
Под несколькими вариантами URL-адресов я подразумеваю, что в данном тексте присутствует несколько URL-адресов.
String text = "Some content which contains link as <A HREF=\"/relative-path/fruit.cgi?param1=abc&param2=xyz\">URL Label</A> and some text after it and another link <A HREF=\"/relative-path/vegetables.cgi?param1=abc&param2=xyz\">URL2 Label</A> and some more text";
Pattern p = Pattern.compile("href=\"(.*?)\"", Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(text);
String url = null;
while (m.find()) {
url = m.group(1); // this variable should contain the link URL
url = appendBaseURI(url);
url = appendQueryParams(url, "license=ABCXYZ");
System.out.println(url);
}




// this is not working
Потому что ваше регулярное выражение чувствительно к регистру.
Пытаться:-
Pattern p = Pattern.compile("href=\"(.*?)\"", Pattern.CASE_INSENSITIVE);
Редактировать1:
Чтобы получить этикетку, используйте Pattern.compile("(?<=>).*?(?=</a>)", Pattern.CASE_INSENSITIVE) и m.group(0).
Редактировать2:
Чтобы заменить тег (включая метку) последней строкой, используйте: -
text.replaceAll("(?i)<a href=\"(.*?)</a>", "new substring here")
Спасибо. Только что узнал об этом. Отредактировали вопрос для того же.
Так это не отвечает на ваш вопрос? Если нет, то какова следующая проблема?
На самом деле 3 проблемы: 1) как мне обрабатывать несколько случаев URL-адресов, 2) Как мне получить метку, 3) После того, как у меня есть URL-адреса с префиксом базового URL-адреса и прикрепленным параметром, как мне заменить их в исходном тексте.
1) что вы имеете в виду под несколько вариантов URL? Вы можете дополнить свой вопрос примером? 2) Обновлен ответ для метки 3) точно так же, как вы заменили раньше, сделайте обратное и, о, используйте replace вместо replaceAll
отредактировал. Я не понял заменяемую часть. Что значит "как будто вы заменили раньше"?
см. мою вторую правку, я надеюсь, что на все ваши вопросы сейчас дан ответ
Шаблон для получения меток не работает в случае текста с несколькими URL-адресами. :( Ненавижу регулярное выражение! Не знаю, когда я его освоу.
Вы можете использовать m.group(0), m.group(1) и т. д., Чтобы получить все группы, запустить replaceAll из моего edit2 и затем объединить их. Или разделите текст ранее в своей программе, а затем запустите replaceAll в цикле. Я сделал сложную часть, связанную с регулярным выражением, теперь вы должны завершить ее.
да. Спасибо друг. Обновлю вопрос, как только у меня будет рабочий пример, и помечу ваш как ответ.
@Nik опубликовал полный код в качестве другого ответа с примером нескольких URL-адресов
Вы можете использовать текст общего доступа apacheStringEscapeUtils для декодирования html-сущностей, а затем replaceAll, то есть:
import org.apache.commons.text.StringEscapeUtils;
String text = "Some content which contains link as <A HREF=\"/relative-path/fruit.cgi?param1=abc&param2=xyz\">URL Label</A> and some text after it";
String output = StringEscapeUtils.unescapeHtml4(text).replaceAll("([^<]+).+\"(.*?)\">(.*?)<[^>]+>(.*)", "$1https://google.com$2&your_param ($3)$4");
System.out.print(output);
// Some content which contains link as https://google.com/relative-path/fruit.cgi?param1=abc¶m2=xyz&your_param (URL Label) and some text after it
Демо:
Это действительно изящно и идеально подходит для моего необходимого решения, если оно может обрабатывать сценарии с несколькими URL-адресами. Кроме того, я предполагаю, что ваше решение предполагает, что URL-адрес всегда должен иметь префикс google.com, что не так, как упоминалось в пункте (2) моего вопроса. Я добавлю базовый URI, только если он отсутствует. Спасибо за ответ! постараюсь расширить его.
сделайте baseurl также динамичным.
public static void main(String args[]) {
String text = "Some content which contains link as <A HREF=\"/relative-path/fruit.cgi?param1=abc&param2=xyz\">URL Label</A> and some text after it and another link <A HREF=\"/relative-path/vegetables.cgi?param1=abc&param2=xyz\">URL2 Label</A> and some more text";
text = StringEscapeUtils.unescapeHtml4(text);
Pattern p = Pattern.compile("<a href=\"(.*?)\">(.*?)</a>", Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(text);
while (m.find()) {
text = text.replace(m.group(0), cleanUrlPart(m.group(1), m.group(2)));
}
System.out.println(text);
}
private static String cleanUrlPart(String url, String label) {
if (!url.startsWith("http") && !url.startsWith("www")) {
if (url.startsWith("/")) {
url = "http://www.google.com" + url;
} else {
url = "http://www.google.com/" + url;
}
}
url = appendQueryParams(url, "myParam=pqr").toString();
if (label != null && !label.isEmpty()) url += " (" + label + ")";
return url;
}
Вывод
Some content which contains link as http://www.google.com/relative-path/fruit.cgi?param1=abc¶m2=xyz&myParam=pqr (URL Label) and some text after it and another link http://www.google.com/relative-path/vegetables.cgi?param1=abc¶m2=xyz&myParam=pqr (URL2 Label) and some more text
о ... не видел этого и отправил свой ответ ... Я просто пытаюсь заменить деталь ... сначала попробую сделать свой ответ ... иначе попробую ваш ... спасибо!
Почти готово:
public static void main(String[] args) throws URISyntaxException {
String text = "Some content which contains link as <A HREF=\"/relative-path/fruit.cgi?param1=abc&param2=xyz\">URL Label</A> and some text after it and another link <A HREF=\"/relative-path/vegetables.cgi?param1=abc&param2=xyz\">URL2 Label</A> and some more text";
text = StringEscapeUtils.unescapeHtml4(text);
System.out.println(text);
System.out.println("**************************************");
Pattern patternTag = Pattern.compile("<a([^>]+)>(.+?)</a>", Pattern.CASE_INSENSITIVE);
Pattern patternLink = Pattern.compile("href=\"(.*?)\"", Pattern.CASE_INSENSITIVE);
Matcher matcherTag = patternTag.matcher(text);
while (matcherTag.find()) {
String href = matcherTag.group(1); // href
String linkText = matcherTag.group(2); // link text
System.out.println("Href: " + href);
System.out.println("Label: " + linkText);
Matcher matcherLink = patternLink.matcher(href);
String finalText = null;
while (matcherLink.find()) {
String link = matcherLink.group(1);
System.out.println("Link: " + link);
finalText = getFinalText(link, linkText);
break;
}
System.out.println("***************************************");
// replacing logic goes here
}
System.out.println(text);
}
public static String getFinalText(String link, String label) throws URISyntaxException {
link = appendBaseURI(link);
link = appendQueryParams(link, "myParam=ABCXYZ");
return link + " (" + label + ")";
}
public static String appendQueryParams(String uriToUpdate, String queryParamsToAppend) throws URISyntaxException {
URI oldUri = new URI(uriToUpdate);
String newQueryParams = oldUri.getQuery();
if (newQueryParams == null) {
newQueryParams = queryParamsToAppend;
} else {
newQueryParams += "&" + queryParamsToAppend;
}
URI newUri = new URI(oldUri.getScheme(), oldUri.getAuthority(),
oldUri.getPath(), newQueryParams, oldUri.getFragment());
return newUri.toString();
}
public static String appendBaseURI(String url) {
String baseURI = "http://www.google.com/";
if (url.startsWith("/")) {
url = url.substring(1, url.length());
}
if (url.startsWith(baseURI)) {
return url;
} else {
return baseURI + url;
}
}
Начните с преобразования HTML-сущностей с помощью:
import org.apache.commons.lang.StringEscapeUtils; String entities_decode = StringEscapeUtils.unescapeHtml(text );