edelwater
edelwater

Reputation: 2802

How can I count the amount of spaces at the start of a string in Perl?

How can I count the amount of spaces at the start of a string in Perl?

I now have:

  $temp = rtrim($line[0]);
  $count = ($temp =~ tr/^ //);

But that gives me the count of all spaces.

Upvotes: 4

Views: 11471

Answers (6)

sfgroups
sfgroups

Reputation: 19109

This prints amount of white space

echo "   hello" |perl -lane 's/^(\s+)(.*)+$/length($1)/e; print'

3

Upvotes: 1

Chas. Owens
Chas. Owens

Reputation: 64929

You can get the offset of a match using @-. If you search for a non-whitespace character, this will be the number of whitespace characters at the start of the string:

#!/usr/bin/perl

use strict;
use warnings;

for my $s ("foo bar", " foo bar", "  foo bar", "  ") {
        my $count = $s =~ /\S/ ? $-[0] : length $s;
        print "'$s' has $count whitespace characters at its start\n";
}

Or, even better, use @+ to find the end of the whitespace:

#!/usr/bin/perl

use strict;
use warnings;

for my $s ("foo bar", " foo bar", "  foo bar", "  ") {
    $s =~ /^\s*/;
    print "$+[0] '$s'\n";
}

Upvotes: 5

CanSpice
CanSpice

Reputation: 35808

$str =~ /^(\s*)/;
my $count = length( $1 );

If you just want actual spaces (instead of whitespace), then that would be:

$str =~ /^( *)/;

Edit: The reason why tr doesn't work is it's not a regular expression operator. What you're doing with $count = ( $temp =~ tr/^ // ); is replacing all instances of ^ and with itself (see comment below by cjm), then counting up how many replacements you've done. tr doesn't see ^ as "hey this is the beginning of the string pseudo-character" it sees it as "hey this is a ^".

Upvotes: 12

Martin Sojka
Martin Sojka

Reputation: 266

Since the regexp matcher returns the parenthesed matches when called in a list context, CanSpice's answer can be written in a single statement:

$count = length( ($line[0] =~ /^( *)/)[0] );

Upvotes: 1

Sinan Ünür
Sinan Ünür

Reputation: 118148

tr/// is not a regex operator. However, you can use s///:

use strict; use warnings;

my $t = (my $s = " \t\n  sdklsdjfkl");
my $n = 0;

++$n while $s =~ s{^\s}{};
print "$n \\s characters were removed from \$s\n";

$n = ( $t =~ s{^(\s*)}{} ) && length $1;
print "$n \\s characters were removed from \$t\n";

Upvotes: 1

Chris Cleeland
Chris Cleeland

Reputation: 4900

Here's a script that does this for every line of stdin. The relevant snippet of code is the first in the body of the loop.

  #!/usr/bin/perl

  while ($x = <>) {
    $s = length(($x =~ m/^( +)/)[0]);
    print $s, ":", $x, "\n";
  }

Upvotes: 1

Related Questions