2010-08-01 7 views
1

Mon post précédent a obtenu les balises partiellement dénudés, si elle est ici encore:Perl: Substition global au sein de balise chaîne délimitée

Mon but est de remplacer toutes les occurrences d'un arrière - à un arrière + entre crochets d'étiquette. Permet de prendre la ligne à remplacer ressemble à ceci:

<h> aa- aa- </h> <h> ba- ba- </h> 

et devrait ressembler à la suite comme

<h> aa+ aa+ </h> <h> ba+ ba+ </h>. 

D'abord, j'ai essayé cette expression:

s/<h>(.*?)-(.*?)<\/h>/<h>$1+$2<\/h>/g; 

qui a produit cette sortie:

<h> aa+ aa- </h> <h> ba+ ba- </h>. 

T L'option he g conduit à plus d'une substitution par ligne, mais seulement pour la première instance par étiquette (et seulement si les deux parenthèses contiennent le point d'interrogation).

Pour affiner le problème, j'ai ensuite essayé d'obtenir une substitution sans tenir compte des étiquettes. L'expression

s/(.*?)-(.*?)/$1+$2/g; 

conduit en effet au résultat souhaité

<h> aa+ aa+ </h> <h> ba+ ba+ </h>. 

Cela remplacera en dehors des supports d'étiquettes ainsi, bien sûr.

Alors, quel est le problème avec ma première expression, et comment puis-je atteindre mon objectif de substitution complète entre les parenthèses?

+0

ne pas poster une nouvelle question si vous n'avez pas réellement une nouvelle question, éditez votre question originale. Vous devriez supprimer cette nouvelle question. – Gilles

Répondre

0

1) option g travaille pour expression régulière Tags démenés

2) utiliser deux fois ou jusqu'à ce qu'aucun changement

0

séparés l'étiquette de sélection et les opérations de substitution:

$str = '<h> aa- aa- </h> <h> ba- ba- </h>'; 
while ($str =~ m!<h>.*?-.*?</h>!) { 
    substr($str, $-[0], $+[0] - $-[0]) =~ y/-/+/; 
} 
print $str, "\n"; 

(Les baies @- et @+ fournissent des informations de décalage sur la dernière correspondance réussie.)

Alternativement:

sub fixup_h_tag { 
    my $tag = shift; 
    $tag =~ y/-/+/; 
    $tag 
} 
$str = '<h> aa- aa- </h> <h> ba- ba- </h>'; 
$str =~ s{ (<h>.*?</h>) }{ fixup_h_tag("$1") }gxe; 
print $str, "\n"; 

Notez que si votre langage de balisage tag permet des commentaires ou des chaînes entre guillemets d'un certain type (qui peut contenir ou non sous forme de balises) ou des espaces facultatifs ou attributs dans la balise h, regexes ne vont pas facilement fournir une solide Solution.

Questions connexes