expresiones regulares javascript para extraer el ancla de texto y la dirección URL de etiquetas de anclaje

StackOverflow https://stackoverflow.com/questions/369147

  •  21-08-2019
  •  | 
  •  

Pregunta

Tengo un párrafo de texto en una variable de JavaScript llamada 'input_content' y que el texto contiene varias etiquetas de anclaje / enlaces. Me gustaría hacer coincidir todas las etiquetas de anclaje y extraer el ancla de texto y URL, y lo puso en una matriz similar (o similares a) lo siguiente:

Array
(
    [0] => Array
        (
            [0] => <a href="http://yahoo.com">Yahoo</a>
            [1] => http://yahoo.com
            [2] => Yahoo
        )
    [1] => Array
        (
            [0] => <a href="http://google.com">Google</a>
            [1] => http://google.com
            [2] => Google
        )
)

Me he tomado una grieta en ella ( http://pastie.org/339755 ), pero estoy perplejo más allá de este punto. Gracias por la ayuda!

¿Fue útil?

Solución

var matches = [];

input_content.replace(/[^<]*(<a href="([^"]+)">([^<]+)<\/a>)/g, function () {
    matches.push(Array.prototype.slice.call(arguments, 1, 4))
});

Esto supone que sus anclajes estarán siempre en la forma <a href="...">...</a> es decir, no va a funcionar si hay cualquier otro atributo (por ejemplo, target). La expresión regular puede ser mejorado para acomodar esto.

Para romper la expresión regular:

/ -> start regular expression
  [^<]* -> skip all characters until the first <
  ( -> start capturing first token
    <a href=" -> capture first bit of anchor
    ( -> start capturing second token
        [^"]+ -> capture all characters until a "
    ) -> end capturing second token
    "> -> capture more of the anchor
    ( -> start capturing third token
        [^<]+ -> capture all characters until a <
    ) -> end capturing third token
    <\/a> -> capture last bit of anchor
  ) -> end capturing first token
/g -> end regular expression, add global flag to match all anchors in string

Cada llamada a nuestra función anónima recibirá tres fichas como el segundo, tercer y cuarto argumentos, a saber argumentos [1], argumentos [2], argumentos [3]:

  • argumentos [1] es la totalidad del ancla
  • argumentos [2] es la parte href
  • argumentos [3] es el texto dentro de

Vamos a utilizar un truco para impulsar estos tres argumentos como una nueva matriz en nuestra gama principal matches. El arguments variable incorporada no es una verdadera matriz de JavaScript, por lo que tendremos que aplicar el método de matriz split en él para extraer los elementos que queremos:

Array.prototype.slice.call(arguments, 1, 4)

Esto va a extraer artículos de <=> comenzando en el índice 1 y terminando (no incluido) en el índice 4.

var input_content = "blah \
    <a href=\"http://yahoo.com\">Yahoo</a> \
    blah \
    <a href=\"http://google.com\">Google</a> \
    blah";

var matches = [];

input_content.replace(/[^<]*(<a href="([^"]+)">([^<]+)<\/a>)/g, function () {
    matches.push(Array.prototype.slice.call(arguments, 1, 4));
});

alert(matches.join("\n"));

Da:

<a href="http://yahoo.com">Yahoo</a>,http://yahoo.com,Yahoo
<a href="http://google.com">Google</a>,http://google.com,Google

Otros consejos

Desde que estés presumiblemente ejecutar el JavaScript en un navegador web, expresiones regulares parece una mala idea para esto. Si el párrafo proviene de la página, en primer lugar, obtener un identificador para el contenedor, llame .getElementsByTagName() para conseguir las anclas, y luego extraer los valores que desea de esa manera.

Si eso no es posible, entonces, crear un objeto nuevo elemento html, asignar el texto a que es propiedad .innerHTML, y luego llamar a <=>.

Creo que Joel tiene la derecha de él - expresiones regulares son conocidos por jugar mal con el formato, ya que hay simplemente demasiadas posibilidades a considerar. ¿Hay otros atributos a las etiquetas de anclaje? ¿En qué orden están en ellos? Es el espacio en blanco que separa siempre un solo espacio? En vista de que ya dispone de un navegador HTML de analizador disponibles, la mejor manera de poner esto en lugar de trabajar.

function getLinks(html) {
    var container = document.createElement("p");
    container.innerHTML = html;

    var anchors = container.getElementsByTagName("a");
    var list = [];

    for (var i = 0; i < anchors.length; i++) {
        var href = anchors[i].href;
        var text = anchors[i].textContent;

        if (text === undefined) text = anchors[i].innerText;

        list.push(['<a href="' + href + '">' + text + '</a>', href, text];
    }

    return list;
}

Esto devolverá una matriz como la que describes, independientemente de cómo se almacenan los enlaces. Tenga en cuenta que puede cambiar la función de trabajar con un elemento pasado en lugar de texto cambiando el nombre del parámetro de "contenedor" y la eliminación de las dos primeras líneas. La propiedad textContent / innerText obtiene el texto mostrado por el enlace, despojado de cualquier tipo de código (en negrita / cursiva / fuente / ...). Se podría sustituir .textContent con .innerHTML y quitar la instrucción interna si () si desea conservar el margen de beneficio.

jQuery sería su mejor apuesta. Este no es el mejor guión y estoy seguro de que otros pueden dar algo mejor. Pero esto crea una matriz de exactamente lo que estás buscando.

<script type="text/javascript">
    // From http://brandonaaron.net Thanks!
    jQuery.fn.outerHTML = function() {
        return $('<div>').append( this.eq(0).clone() ).html();
    };    

    var items = new Array();
    var i = 0;

    $(document).ready(function(){
        $("a").each(function(){
            items[i] = {el:$(this).outerHTML(),href:this.href,text:this.text};
            i++;      
        });
    });

    function showItems(){
        alert(items);
    }

</script>

Para extraer la url:

patrón var = /.href="(.)".*/; var url = String.Replace (patrón, '$ 1');

Demostración:

//var string = '<a id="btn" target="_blank" class="button" href="https://yourdomainame.com:4089?param=751&amp;2ndparam=2345">Buy Now</a>;'
//uncomment the above as an example of link.outerHTML

var string = link.outerHTML
var pattern = /.*href="(.*)".*/;
var href = string.replace(pattern,'$1');
alert(href)

Para "anchor text", ¿por qué no usar: link.innerHtml

Para el beneficio de los buscadores: He creado algo que va a trabajar con atributos adicionales en la etiqueta de anclaje. Para aquellos que no están familiarizados con la expresión regular, el dólar de los valores ($ 1, etc.) son el grupo expresión coincide.

var text = 'This is my <a target="_blank" href="www.google.co.uk">link</a> Text';
var urlPattern = /([^+>]*)[^<]*(<a [^>]*(href="([^>^\"]*)")[^>]*>)([^<]+)(<\/a>)/gi;
var output = text.replace(urlPattern, "$1___$2___$3___$4___$5___$6");
alert(output);

Vea trabajo jsFiddle y regex101 .

Como alternativa, se puede obtener información de los grupos como este:

var returnText = text.replace(urlPattern, function(fullText, beforeLink, anchorContent, href, lnkUrl, linkText, endAnchor){
                    return "The bits you want e.g. linkText";
                });
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top