2010-08-03 8 views
0

J'ai la chaîne suivante dans un fichier et que vous voulez tronquer la chaîne à pas plus de 6 caractères. comment faire cela en utilisant l'expression régulière dans Perl?
le fichier original est:comment tronquer une chaîne en utilisant l'expression régulière dans perl

chat shortstring.in:

<value>[email protected]</value>
<value>[email protected]</value>

Je veux obtenir le fichier comme:
chat shortstring.out

<value>[email protected]</value>
<value>[email protected]</value>

J'ai un code comme suit, est-il plus efficace que d'utiliser
s/<value>(\w\w\w\w\w\w)(.*)/$1/;?

est ici une partie de mon code:

while (<$input_handle>) {      # take one input line at a time 
      chomp; 
      if (/(\[email protected])/) { 
        s/(<value>\w\w\w\w\w\w)(.*)</value>/$1/; 
        print $output_handle "$_\n"; 
       } else { 
       print $output_handle "$_\n"; 
      } 
    } 
+1

@ n'est pas un caractère de mot si ne correspond pas à \ w. Aussi, je pense que vous ne voulez pas supprimer la partie ''? – ysth

Répondre

5
$ perl -pe 's/(<value>[^<]{1,6})[^<]*/$1/' shortstring.in 
<value>[email protected]</value> 
<value>[email protected]</value>

Dans le contexte de l'extrait de votre question, utilisez

while (<$input_handle>) { 
    s!(<value>)(.*?)(</value>)!$1 . substr($2,0,6) . $3!e 
    if /(\d+\@google\.com)/; 
    print $output_handle $_; 
} 

ou le faire avec un seul motif

while (<$input_handle>) { 
    s!(<value>)(\d+\@google\.com)(</value>)!$1 . substr($2,0,6) . $3!e; 
    print $output_handle $_; 
} 

Utilisation de la frange comme délimiteur L'opérateur de substitution empêche Leaning Toothpick Syndrome dans </value>.

REMARQUE: L'habituel warnings à propos de l'analyse syntaxique XML avec des expressions régulières s'applique.

programme de démonstration:

#! /usr/bin/perl 

use warnings; 
use strict; 

my $input_handle = \*DATA; 
open my $output_handle, ">&=", \*STDOUT or die "$0: open: $!"; 

while (<$input_handle>) { 
    s!(<value>)(\d+\@google\.com)(</value>)!$1 . substr($2,0,6) . $3!e; 
    print $output_handle $_; 
} 

__DATA__ 
<value>[email protected]</value> 
<value>[email protected]</value> 
<value>[email protected]</value> 

Sortie:

$ ./prog.pl 
<value>[email protected]</value> 
<value>[email protected]</value> 
<value>[email protected]</value>
+0

Je pense que mon code n'est pas correct, je veux seulement tronquer les données entre user399517

+2

Pourquoi pensez-vous que ce n'est pas correct? –

+0

votre ne fonctionne pas. enfin j'utilise ceci: s/(. {1, $ truncate_num}). * (<. *)/$ 1 $ 2 /; – user399517

1

On dirait que vous voulez tronquer le texte dans la balise qui pourrait être plus courte que 6 caractères déjà, auquel cas:

s/(<value>[^<]{1,6})[^<]*/$1/ 
0
s/<value>(.{1,6}).*/<value>$1</value>/; 
+0

Avec le. dans (. {1,6}) vous pourriez obtenir des trucs comme '123

+0

@David, non, parce qu'il a déjà testé pour s'assurer que le tag a '@ google.com', donc il ne peut pas être plus petit que ça. Si vous voulez faire plus attention, vous pouvez tester la balise de fermeture, mais depuis l'analyse xml ou html dans une regex est vraiment une idée vraiment mauvaise, je ne veux pas lui donner des idées. –

10

Utilisez ce lieu (regex n'est pas la seule caractéristique de Perl et il est surpuissant pour cela: :-)

$str = substr($str, 0, 6); 

http://perldoc.perl.org/functions/substr.html

+1

+1 pour me rappeler que regex n'est pas la seule fonctionnalité de Perl .-) –

1

Essayez ceci:

s|(?<=<value>)(.*?)(?=</value>)|substr $1,0,6|e; 
Questions connexes