When you say the "first" digit, I guess you mean the
leftmost. The easiest way I can think of is with a pattern
match, e.g.,
$x = 12345;
$first_digit = $1 if $x =~ /^(\d)\d*$/;
The second statement just means, "If $x consists of a single
digit followed by zero or more digits (it always will if it's numeric) return the part that matched what's inside
the parentheses (the first digit)."
As for repeating something over and over until a condition is met, there are lots of ways to do this. Choosing the
appropriate way depends on what you're trying to do.
Can you give me an example?
Okay that second part looks really complex but your explanation makes it simpler. I'll give it a try. Since I am trying to learn Perl I'd appreciate if you broke it down piece by pice and explain what each does. ie. ~ does this and / does that ^ is in there for, whatever. Please don't feel obligated to do this, but if you have time to kill, go ahead. As for the repeat thing I would like to take a number and as long as it is greater than 10, divide it by 10 until it becomes less than 10 and then stop.
could also be written like this, which may make it
clearer:
if ($x =~ m/^(\d)\d*$/) {
$first_digit = $1;
}
The "=~" is like "equals" but is used in pattern matching
instead of the "==" (numeric) or "eq" (string) comparison
operators. I've used "m" (for match) here before the pattern, but Perl just assumes this is what you mean if it's
left out. The "/"'s around the pattern just open and close
the pattern; it's like quoting. The "^" means "at the
beginning of the field" and "$" means "at the end of the
field". Since we're using "^" and "$" to anchor the pattern, $x must consist entirely of numeric characters
(which means that it wouldn't work on numbers with decimal
points or negative numbers, actually). "\d" means "a single
digit" and "\d*" means "zero or more digits".
$1 is the part of the pattern that matched what's inside
the parentheses. You can have multiple parentheses. The
first parenthesized match is stored in $1, the second in
$2, and so on. For example:
In Perl you can put a condition test AFTER a single statement to execute if the condition is true, as I did in
the above example. This has the advantage that you can
omit the parentheses around the condition and the curly
braces around the statement that depends on it, which are
required otherwise.
As for dividing a number repeatedly by 10 as long as it's
greater than 10, I guess that would be the strategy for
extracting the first digit from a number if Perl didn't
have pattern matching. How about this:
The second line says "divide $x by 10 and store the result
back into $x as long as $x >= 10". There are a couple
problems with this, though. We lose the original value of
$x, if we cared about it, and also when we print out $x at
the end, we don't get the "1" we had hoped for, but 1.2345,
because division in Perl is a floating-point operation.
We can get around that this way:
$x = 12345;
$q = $x; # so original value of $x isn't lost
while ($q >= 10) {
$q = $q / 10;
}
$q = sprintf "%d", $q;
print "$q\n";
Here we just stored $x into another variable $q before we
start dividing. I also wrote the loop and the division in
a more traditional, less "perlish" way. After the loop,
I use the sprintf() function with a "%d" (digit) specification, to truncate $q to integer and then store the
result back into $q. This gives us the "1" we were hoping
for. The "\n" in the print statement just prints a newline
after $q so the cursor goes to the next line.
Q: How do you take a number and just keep the first digit?
A: Many ways to do this(as already indicated) - for me, "substring" or "unpack" come to mind.
---------------------------------------
Q: I'd also like to know how to repeat something over and over until the condition is met..
A: while (1) {
if (condition) {
### condition is met ###
last;
}
### this is where you put code that will
### be done over and over, until the
### condition is met
I know that the % operator doesn't give the first digit, in fact with % 10 it gives the LAST digit. However, there is also a discussion up above about dividing repeatedly by 10 until the result is less than 10, and the % operator will do exactly that, without looping or conditionals.
As for extracting the first digit - if you know that the first character of the string is the first digit, I'd use substr. If there might be other characters, like spaces, before the first digit, I'd use a regular expression. Tracy Dryden
tracy@bydisn.com
I like the regexp approach. Though Perl doesn't care if
you use a string function like substr on a number, some
languages do, and I guess I've absorbed enough of their
world-view to bias me against that sort of thing, when I
can avoid it.
I want to simply take whatever junk people put into my zip code field and grab the first five digits, and assign them to a variable so I can use them ..
What I have is this, and it's not working...
#--------------------------------------------------------------------
# TB Aug 1-02 -- new stuff that limits the zip code entry to
# first 5 digits for USA orders...
Ok remove the $ from the end of your regexp and it should work. Your setting $first_five_digits to the first five digits of a 5 digit zip only. It shouldn't match a 9 digit zip at all.
Your regexp is matching ^ start of the string, followed directly by exactly 5 instances of [0-9] followed DIRECTLY by the end of the string ($).
Also if you want to imporve it a bit, remove all non-digits first so that if somebody were to type z54905 by mistake it won't potentially screw up your script.
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.