¿Cómo reemplazo varias palabras, cada una de las cuales se convierte en una palabra alternativa, en un atributo HTML usando Perl regex?

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

  •  07-07-2019
  •  | 
  •  

Pregunta

Estoy escribiendo un ofuscador HTML, y tengo un hash que correlaciona nombres fáciles de usar (de identificadores y clases) con nombres ofuscados (como a, b, c, etc.). Tengo problemas para encontrar una expresión regular para lograr reemplazar algo como

<div class="left tall">

con

<div class="a b">

Si las etiquetas solo pudieran aceptar una clase, la expresión regular sería simplemente algo así como

s/(class|id)="(.*?)"/$1="$hash{$2}"/

¿Cómo debo corregir esto para tener en cuenta varios nombres de clase entre comillas? Preferiblemente, la solución debería ser compatible con Perl.

¿Fue útil?

Solución

Creo que haría esto:

s/  
    (class|id)="([^"]+)"
/   
    $1 . '="' . (
        join ' ', map { $hash{

Creo que haría esto:

<*>} } split m!\s+!, $2 ) . '"' /ex;

Otros consejos

No deberías estar usando una expresión regular para esto en primer lugar. Está intentando hacer demasiado con una expresión regular (consulte ¿Puede proporcionar algunos ejemplos de por qué es difícil analizar XML y HTML con una expresión regular? por qué). Lo que necesitas es un analizador HTML. Consulte ¿Puede proporcionar un ejemplo de análisis HTML con su analizador favorito? para obtener ejemplos utilizando una variedad de analizadores.

Eche un vistazo a HTML :: Parser . Aquí hay una implementación, probablemente incompleta:

#!/usr/bin/perl

use strict;
use warnings;

use HTML::Parser;

{
    my %map = (
        foo => "f",
        bar => "b",
    );

    sub start {
        my ($tag, $attr) = @_;
        my $attr_string = '';
        for my $key (keys %$attr) {
            if ($key eq 'class') {
                my @classes = split " ", $attr->{$key};
                #FIXME: this should be using //, but
                #it is only availble starting in 5.10
                #so I am using || which will do the
                #wrong thing if the class is 0, so
                #don't use a class of 0 in %map , m'kay
                $attr->{$key} = join " ", 
                    map { $map{

No deberías estar usando una expresión regular para esto en primer lugar. Está intentando hacer demasiado con una expresión regular (consulte ¿Puede proporcionar algunos ejemplos de por qué es difícil analizar XML y HTML con una expresión regular? por qué). Lo que necesitas es un analizador HTML. Consulte ¿Puede proporcionar un ejemplo de análisis HTML con su analizador favorito? para obtener ejemplos utilizando una variedad de analizadores.

Eche un vistazo a HTML :: Parser . Aquí hay una implementación, probablemente incompleta:

<*>} ||

No deberías estar usando una expresión regular para esto en primer lugar. Está intentando hacer demasiado con una expresión regular (consulte ¿Puede proporcionar algunos ejemplos de por qué es difícil analizar XML y HTML con una expresión regular? por qué). Lo que necesitas es un analizador HTML. Consulte ¿Puede proporcionar un ejemplo de análisis HTML con su analizador favorito? para obtener ejemplos utilizando una variedad de analizadores.

Eche un vistazo a HTML :: Parser . Aquí hay una implementación, probablemente incompleta:

<*> } @classes; } $attr_string .= qq/ $key="$attr->{$key}"/; } print "<$tag$attr_string>"; } } sub text { print shift; } sub end { my $tag = shift; print "</$tag>"; } my $p = HTML::Parser->new( start_h => [ \&start, "tagname,attr" ], text_h => [ \&text, "dtext" ], end_h => [ \&end, "tagname" ], ); $p->parse_file(\*DATA); __DATA__ <html> <head> <title>foo</title> </head> <body> <span class="foo">Foo!</span> <span class="bar">Bar!</span> <span class="foo bar">Foo Bar!</span> This should not be touched: class="foo" </body> </html>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top