web-dev-qa-db-fra.com

Comment supprimer des espaces dans une chaîne Perl?

Si j'ai déclaré une variable $myString avec la valeur '3 ' (remarquez l'espace blanc) . Existe-t-il une fonction permettant de supprimer l'espace blanc de la valeur renvoyée . Un peu comme SomeFun($myString) puis renvoyer '3' (sans espace blanc).

#!C:\Perl\bin\Perl.exe
use strict;
use warnings;
use Data::Dumper; 

my $fh = \*DATA; 

print Dumper parse_constant_spec( $fh ); 


# Parse a constant spec file. 
# Pass in a handle to process. 
# As long as it acts like a file handle, it will work. 
sub parse_constant_spec { 
    my $fh = shift; 

    my %spec; 

    # Until file is done: 
        # Read in a whole block 
    while( my $block = read_block($fh) ) { 

        # Parse the and return key/value pairs for a hash. 
        my %constant = parse_block( $block ); 

        # Store a ref to the hash in a big hash of all blocks, keyed by constant_name. 
        $spec{ $constant{const_name} } = \%constant; 

    } 

    # Return ref to big hash with all block data 
    return \%spec; 
} 

# Read a constant definition block from a file handle. 
# void return when there is no data left in the file. 
# Otherwise return an array ref containing lines to in the block.  
sub read_block { 
    my $fh = shift; 

    my @lines; 
    my $block_started = 0; 

    while( my $line = <$fh> ) { 

        $block_started++ if $line =~ /^constant/; 

        if( $block_started ) { 

            last if $line =~ /^\s*$/; 

            Push @lines, $line; 
        } 
    } 

    return \@lines if @lines; 

    return; 
} 


sub parse_block { 
    my $block = shift; 
    my ($start_line, @attribs) = @$block; 

    my %constant; 

    # Break down first line: 
    # First separate assignment from option list. 
    my ($start_head, $start_tail) = split /=/, $start_line; 

    # work on option list 
    my @options = split /\s+/, $start_head; 

    # Recover constant_name from options: 
    $constant{const_name} = pop @options; 
    $constant{options} = \@options; 

    # Now we parse the value/type specifier 
    @constant{'type', 'value' } = parse_type_value_specifier( $start_tail ); 

    # Parse attribute lines. 
    # since we've already got multiple per line, get them all at once. 
    chomp @attribs; 
    my $attribs = join ' ', @attribs; 

    #  we have one long line of mixed key = "value" or key = <TYPE VALUE>  

    @attribs = $attribs =~ /\s*(\w+\s+=\s+\w+\s+|\w+\s+=\s+".*?"|\w+\s+=\s+<.*?>)\s*/g; 

    for my $attrib ( @attribs ) { 
        warn "$attrib\n"; 
        my ($name, $value) = split /\s*=\s*/, $attrib; 

        if( $value =~ /^"/ ) {  
            $value =~ s/^"|"\s*$//g; 
        } 
        elsif( $value =~ /^</ ) { 
           $value = [ parse_type_value_specifier( $start_tail ) ]; 
        } 
        else { 
            warn "Bad line"; 
        } 

        $constant{ $name } = $value; 
    } 

    return %constant; 
} 

sub parse_type_value_specifier { 
    my $tvs = shift; 

    my ($type, $value) = $tvs =~ /<(\w+)\s+(.*?)>/; 

    return $type, $value; 
} 

__DATA__ 
constant fixup GemEstabCommDelay = <U2 20> 
    vid = 6 
    name = "ESTABLISHCOMMUNICATIONSTIMEOUT" 
    units = "s" 
    min = <U2 0> 
    max = <U2 1800> 
    default = <U2 20> 


constant fixup private GemConstantFileName = <A "C:\\TMP\\CONST.LOG"> 
    vid = 4 
    name = ""  units = "" 


constant fixup private GemAlarmFileName = <A "C:\\TMP\\ALARM.LOG"> 
    vid = 0 
    name = "" 
    units = ""   

Sortie:

D:\learning\Perl>hello1.pl
vid = 6
Bad line at D:\learning\Perl\hello1.pl line 102, <DATA> line 8.
name = "ESTABLISHCOMMUNICATIONSTIMEOUT"
units = "s"
min = <U2 0>
max = <U2 1800>
default = <U2 20>
vid = 4
Bad line at D:\learning\Perl\hello1.pl line 102, <DATA> line 13.
name = ""
units = ""
vid = 0
Bad line at D:\learning\Perl\hello1.pl line 102, <DATA> line 18.
name = ""
units = ""
$VAR1 = {
          'GemAlarmFileName' => {
                                  'vid' => '0      ',
                                  'options' => [
                                                 'constant',
                                                 'fixup',
                                                 'private'
                                               ],
                                  'value' => '"C:\\\\TMP\\\\ALARM.LOG"',
                                  'name' => '',
                                  'type' => 'A',
                                  'const_name' => 'GemAlarmFileName',
                                  'units' => ''
                                },
          'GemEstabCommDelay' => {
                                   'vid' => '6      ',
                                   'options' => [
                                                  'constant',
                                                  'fixup'
                                                ],
                                   'value' => '20',
                                   'min' => [
                                              'U2',
                                              '20'
                                            ],
                                   'name' => 'ESTABLISHCOMMUNICATIONSTIMEOUT',
                                   'max' => [
                                              'U2',
                                              '20'
                                            ],
                                   'default' => [
                                                  'U2',
                                                  '20'
                                                ],
                                   'type' => 'U2',
                                   'units' => 's',
                                   'const_name' => 'GemEstabCommDelay'
                                 },
          'GemConstantFileName' => {
                                     'vid' => '4      ',
                                     'options' => [
                                                    'constant',
                                                    'fixup',
                                                    'private'
                                                  ],
                                     'value' => '"C:\\\\TMP\\\\CONST.LOG"',
                                     'name' => '',
                                     'type' => 'A',
                                     'const_name' => 'GemConstantFileName',
                                     'units' => ''
                                   }
        };

D:\learning\Perl>

Vous pourriez remarquer que 'vid' => '0 ', (remarquez l'espace blanc) 

Le code ci-dessus de la réponse . Je suis en train de l'étudier. :-)

Je vous remercie. 

13
Nano HE
$myString =~ s/^\s*(.*?)\s*$/$1/;

Cela réduira les espaces des deux côtés.

de juste à droite:

$myString =~ s/\s*$//;
24
JAL

Si votre espace blanc n'est que des espaces, le code suivant supprimera tous les espaces:

$mystring =~ tr/ //ds;
13
Chip Uni
sub trim($)
{
    my $string = shift;
    $string =~ s/^\s+//;
    $string =~ s/\s+$//;
    return $string;
}


print trim($myString)
11
GxG

Essaye ça:

# Delete leading/trailing whitespace.
$string =~ s/^\s+|\s+$//g;
8
John Feminella

Une autre solution possible est Text :: Trim de CPAN, qui "supprimera les espaces de début et/ou de fin des chaînes". Il a une fonction trim qui peut répondre à vos besoins.

5
toolic

Voici un sous-programme qui vous permettra de supprimer les espaces blancs de début et de fin d'une chaîne tout en supprimant les espaces superflus de la chaîne et en les remplaçant par un seul espace.

-- routine

sub unspace { my @stringer = @_ ? @_ : $; $ = join( ' ', split(' ')) for @stringer; return wantarray ? @stringer : "@stringer"; }

-- usage

$MySpacedString = ' String with tabs double-spaces and other whitespace areas. '; $MyCleanString = unspace($MySpacedString);

2
DoctorLouie
sub trim
{
    my $str = $_[0];
    $str=~s/^\s+|\s+$//g;
    return $str;
}

print trim(" 4 ");
2
ghostdog74

En regardant simplement votre programme, j'ai trouvé 3 points qui pourraient être améliorés ou corrigés.

Je m'excuse si mon code ne se formate pas bien. :-(

Dans votre fonction parse_block (...), 3 éléments nécessitent votre attention.

@attribs = $attribs =~ /\s*(\w+\s+=\s+\w+\s+|\w+\s+=\s+".*?"|\w+\s+=\s+<.*?>)\s*/g;

Pour éliminer les espaces après vid => '6', n'incluez pas le\s + à la fin de votre première sous-expression régulière.

Écrivez-le comme:

@attribs = $attribs =~ /\s*(\w+\s+=\s+\w+|\w+\s+=\s+".*?"|\w+\s+=\s+<.*?>)\s*/g;  

$value = [ parse_type_value_specifier( $start_tail ) ];  

Vous voulez cela à la place:

$value = [ parse_type_value_specifier( $value ) ]; 

(Notez que le paramètre de la fonction doit être $ value et non pas $ start_tail.) Vous n'avez probablement pas remarqué cela.

Dans la boucle pour @attributes, le paramètre "else" de la condition if/else est activé lorsque la "valeur" a une valeur en clair, (pas "" ou <...> éléments dans "valeur").

Mise à jour: paramètre modifié dans 

parse_type_value_specifier (...)
à $ valeur. C'était (à tort) indiqué comme $ attrib.

1
Chris Charley

Si vous souhaitez utiliser un module CPAN, les options String::Util ou un peu plus économique Text::Trim seraient possibles. 

Le réglage des cordes est l’un de ces remises que tout le monde aime construire! Voir le court tutoriel perlmaven by @szabgab pour un petit échantillon de TIMTOWDI fun.

0
G. Cito

Supprimer tous les espaces d'une chaîne:

$string =~ s/ //g;
0
Akhtar Jahan

Je suggère que vous utilisiez le module Text::Trim , qui fournit ltrim, rtrim et trim, qui permettront de supprimer les paramètres passés, ou $_ si vous ne spécifiez aucun paramètre. Ce n'est pas un module de base, il peut donc être nécessaire de l'installer

0
Borodin

Supprimez les espaces de la variable $test (eq rtrim(ltrim(@sStr)) de Transact SQL:

$test =~s/^\s*(\S*)\s*$/$1/;
0
user2075567