Java regex para recuperar el enlace del texto

Tengo una entrada Stringcomo:

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";

Quiero convertir este texto a:

Some content which contains link as http://www.google.com/relative-path/fruit.cgi?param1=abc&param2=xyz&myParam=pqr (URL Label) and some text after it

Entonces aquí:

1) Quiero reemplazar la etiqueta de enlace con un enlace simple. Si la etiqueta contiene etiqueta, debe ir entre llaves después de la URL.

2) Si la URL es relativa, quiero prefijar la URL base ( http://www.google.com ).

3) Quiero agregar un parámetro a la URL. (& myParam = pqr)

Tengo problemas para recuperar la etiqueta con URL y etiqueta, y reemplazarla.

Escribí algo como:

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("&lt;", "<");
    text = text.replaceAll("&gt;", ">");
    text = text.replaceAll("&amp;", "&");

    // this is not working
    Pattern p = Pattern.compile("target='_blank' 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;
}

Editar1:

Pattern p = Pattern.compile("HREF=\"(.*?)\"");

Esto funciona. Pero entonces quiero que sea agnóstico de capitalización. Href, HRef, href, hrEF, etc. todo debería funcionar.

Además, ¿cómo manejo si mi texto tiene varias URL?

Edit2:

Algunos progresos.

Pattern p = Pattern.compile("target='_blank' href=\"(.*?)\"");
Matcher m = p.matcher(text);
String url = null;
while (m.find()) {
  url = m.group(1);
  System.out.println(url);
}

Esto maneja el caso de múltiples URL.

El último problema pendiente es, ¿cómo puedo obtener la etiqueta y reemplazar las etiquetas href en el texto original con URL y etiqueta?

Edit3:

Por múltiples casos de URL, quiero decir que hay múltiples url presentes en el texto dado.

String text = "Some content which contains link as &lt;A HREF=\"/relative-path/fruit.cgi?param1=abc&amp;param2=xyz\"&gt;URL Label&lt;/A&gt; and some text after it and another link &lt;A HREF=\"/relative-path/vegetables.cgi?param1=abc&amp;param2=xyz\"&gt;URL2 Label&lt;/A&gt; and some more text";

Pattern p = Pattern.compile("target='_blank' 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);
}
Respuesta 1
public static void main(String args[]) {
    String text = "Some content which contains link as &lt;A HREF=\"/relative-path/fruit.cgi?param1=abc&amp;param2=xyz\"&gt;URL Label&lt;/A&gt; and some text after it and another link &lt;A HREF=\"/relative-path/vegetables.cgi?param1=abc&amp;param2=xyz\"&gt;URL2 Label&lt;/A&gt; and some more text";
    text = StringEscapeUtils.unescapeHtml4(text);
    Pattern p = Pattern.compile("<a target='_blank' 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;
}

Salida

Some content which contains link as http://www.google.com/relative-path/fruit.cgi?param1=abc&param2=xyz&myParam=pqr (URL Label) and some text after it and another link http://www.google.com/relative-path/vegetables.cgi?param1=abc&param2=xyz&myParam=pqr (URL2 Label) and some more text
Respuesta: 2

Puede usar el texto de apache commons StringEscapeUtils para decodificar las entidades html y luego replaceAll, es decir:

import org.apache.commons.text.StringEscapeUtils;

String text = "Some content which contains link as &lt;A HREF=\"/relative-path/fruit.cgi?param1=abc&amp;param2=xyz\"&gt;URL Label&lt;/A&gt; 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&param2=xyz&your_param (URL Label) and some text after it

Población:

  1. jdoodle
  2. Explicación de expresiones regulares
Respuesta: 3

// esto no está funcionando

Porque tu expresión regular distingue entre mayúsculas y minúsculas.

Tratar:-

Pattern p = Pattern.compile("target='_blank' href=\"(.*?)\"", Pattern.CASE_INSENSITIVE);

Edit1 :
para obtener la etiqueta, use Pattern.compile("(?<=>).*?(?=</a>)", Pattern.CASE_INSENSITIVE)y m.group(0).

Edit2 :
para reemplazar la etiqueta (incluida la etiqueta) con su cadena final, use: -

text.replaceAll("(?i)<a target='_blank' href=\"(.*?)</a>", "new substring here")
Respuesta: 4

Tengo una tarea para crear una matriz int que se encuentra en otro método para un valor int de entrada del usuario y luego muestra el índice de ese elemento en la matriz. Tengo esa parte funcionando bien y yo ...

He estado trabajando en una ventana de diálogo para una aplicación de escritorio que estoy desarrollando actualmente. El cuadro de diálogo debe tener un número predeterminado de campos de texto (en otras palabras, variable), pero encontré un error extraño ...

Error Mis códigos Hice un programa que pregunta el nombre completo, la dirección, etc. Quiero que el programa detecte si dos nombres completos son iguales. Ya tengo la instrucción if else que detecta si el nombre completo es el mismo ...

He generado una clase de usuario que incluye el nombre y el apellido. Quiero preguntar cómo puedo generar diferentes nombres aleatorios usando el generador aleatorio. import java.util.ArrayList; importar ...