简体   繁体   中英

In Perl, how can I tell if a string is a number, but without using modules?

I have an array, each element is a string which consists of several words. The first word is identifier, which will not be considered. The rest part of the string would be number or alphabet only. I want to sort the alphabet part and then output the whole element. Following are my codes.

#!/usr/bin/perl

use strict;
use warnings;

my @log=("a1 9 2 3 1","gl cct car","zo4 4 7", "abl off key dog","a8 act zoo");

my @values;
my @letter_log;
my @letter_idf;
my @dig_log;
my $i;
$i=0;
foreach(@log)
{
  @values=split(/\s+/,$_);chomp(@values);
  @_= m/$values[0]\s/;
print "25 \$'=$';\n";
  if($' =~ /\D\s+/){$letter_idf[$i]=$values[0];$letter_log[$i]="$'";}
  else{$dig_log[$i]=$_;}

  $i++;
}

@_=sort { $letter_log[$a] cmp $letter_log[$b] } 0..$#letter_log;
chomp(@_);
enter code here
for($i=0;$i<=$#letter_log;$i++){print"$letter_idf[$_[$i]]"."$letter_log[$_[$i]];\t";}


foreach(@dig_log){print "$_;\t";}

print "\n";

I hope the output is like below

( "g1 act car"; "a8 act zoo"; "ab1 off key dog"; "a1 9 2 3 1"; "zo4 4 7")

However, my @letter_log is empty. I highly appreciate it if you could point out the errors and provide a correct solution.

PLEASE DO NOT USE MODULES, LIKE

import Scalar::Util qw(look_like_number);

I tried to avoid the modules because I want to study how to tell if a string is a number or not. Thanks!

The provided code that demonstrates your intention is not a perfect match for the title since it does a lot more. I would like to address only the main question in the title here.

If you can first define what a number is (instead of using a indirect definition of "whatever perl think a numbers is"), it becomes an easier problem.

For example, if you define the number you are looking for as a string with multiple characters of digit 0..9, then a simple regular expression /^[0-9]+$/ can serve your purpose.

Thanks for comments ikegami and melpomene.

The reason why I want to try it because the module is a "program" as well. I want to learn how to realize it by myself. After all, we meet all kinds of data which need to handle.

After many failures and tests, I figured it out and share it here.

first, the system variable "$'"changed before I assign it in if statement. I save it into another variable. Second, I use an alternative way to realize it because the sequence numbers with spaces must be string. So, I only take one "character" to test it. It proves that this operation is correct. Do not forget the statements in my original post

"The first word is identifier, which will not be considered. The rest part of the string would be number or alphabet only. "

Here are my revised scripts. "NOTHING IS IMPOSSIBLE."

#!/usr/bin/perl -w

use strict;
use warnings;
#import Scalar::Util qw(look_like_number);

my @log=("a1 9 2 3 1","gl act car","zo4 4 7", "abl off key dog","a8 act zoo");
print "original log:\n";
$"=";\t";   #control array's delimiter
print "@log\n";

my @values;
my @letter_log;
my @letter_idf;
my @dig_log;
my $s;
my $i;
my $s_r;

$i=0;
foreach(@log)
{
  @values=split(/\s+/,$_);chomp(@values);
  @_= m/$values[0]\s/;
print "25 \$'=$';\n";
  $s=$';
  $s_r=substr($s,0,1);
  if($s_r =~ /\D/)  
  {  print"26.0: $'\ts=$s\ts_r=$s_r\n";    
     $letter_idf[$i]=$values[0];
     $letter_log[$i]=$s;
     print "26:  $letter_idf[$i]\t$letter_log[$i]\n";$i++;
  }
  else{$dig_log[$i]=$_;}
}

@_=sort { $letter_log[$a] cmp $letter_log[$b] } 0..$#letter_log;
chomp(@_);

print"35:  srt letter  log: @letter_log\n";
#foreach(@letter_log){print "$_;\t";}

print"38: nsrt letter log: ";
for($i=0;$i<=$#letter_log;$i++){print"$letter_idf[$_[$i]] "."$letter_log[$_[$i]];\t";}
print"\n";
print"41: digital log:";
foreach(@dig_log){print "$_;\t";}

print "\n";

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM