Comment remplacer plusieurs mots, chacun haché en un autre mot, dans un attribut HTML à l'aide de l'expression rationnelle Perl?

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

  •  07-07-2019
  •  | 
  •  

Question

J'écris un obscurcisseur HTML et j'ai un hachage qui associe des noms conviviaux (des ids et des classes) à des noms obscurcis (comme a, b, c, etc.). J'ai du mal à trouver une expression rationnelle pour remplacer quelque chose comme

<div class="left tall">

avec

<div class="a b">

Si les tags ne pouvaient accepter qu'une classe, l'expression rationnelle serait simplement quelque chose comme

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

Comment dois-je corriger cela pour tenir compte de plusieurs noms de classe entre guillemets? De préférence, la solution doit être compatible avec Perl.

Était-ce utile?

La solution

Je suppose que je ferais ceci:

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

Je suppose que je ferais ceci:

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

Autres conseils

Vous ne devriez pas utiliser de regex pour cela en premier lieu. Vous essayez de faire trop avec une regex (voir Pouvez-vous donner quelques exemples de la raison pour laquelle il est difficile d'analyser XML et HTML avec une regex? pour pourquoi). Ce dont vous avez besoin est un analyseur HTML. Voir Pouvez-vous fournir un exemple d'analyse HTML avec votre analyseur préféré? pour des exemples utilisant divers analyseurs.

Jetez un coup d’œil à HTML :: Parser . Voici une implémentation probablement incomplète:

#!/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{

Vous ne devriez pas utiliser de regex pour cela en premier lieu. Vous essayez de faire trop avec une regex (voir Pouvez-vous donner quelques exemples de la raison pour laquelle il est difficile d'analyser XML et HTML avec une regex? pour pourquoi). Ce dont vous avez besoin est un analyseur HTML. Voir Pouvez-vous fournir un exemple d'analyse HTML avec votre analyseur préféré? pour des exemples utilisant divers analyseurs.

Jetez un coup d’œil à HTML :: Parser . Voici une implémentation probablement incomplète:

<*>} ||

Vous ne devriez pas utiliser de regex pour cela en premier lieu. Vous essayez de faire trop avec une regex (voir Pouvez-vous donner quelques exemples de la raison pour laquelle il est difficile d'analyser XML et HTML avec une regex? pour pourquoi). Ce dont vous avez besoin est un analyseur HTML. Voir Pouvez-vous fournir un exemple d'analyse HTML avec votre analyseur préféré? pour des exemples utilisant divers analyseurs.

Jetez un coup d’œil à HTML :: Parser . Voici une implémentation probablement incomplète:

<*> } @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>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top