Hallo, es ist OT und deshalb bitte Antwort per PM an steiger@web.de: Mein Freund sucht eine Möglichkeit in Perl zu unterscheiden, ob eine Variable einen Zahlenwert oder ein Wort enthält. Hintergrund: Mein Freund baut an einem Importfilter. Er liest die Ausgangsdatei zeilenweise ein und wandelt die Standartausdrücke z.B line (x1,y1,x2,y2) per Stringoperationen in die neue Form um. Im Einzelnen: Er weist die Zeile einer Variablen 'Zeile' zu, die er dann nach Strukturelementen auftrennt. Die Strukturelemente werden Variablen zugeordnet und per Entscheidungsbäume umgwewandelt. Auftrennen am Beispiel line( x1 y1 x2 y2 ) Es gibt weiterhin auch Sonderausdrücke der Form line(Beschreibung,x1,y1,x2,y2,x3,y3,... ) hier ist die Auftrennung: line( Beschreibung <- hier hat die Variable einen String als Inhalt statt wie üblich eine Zahl x1 y1 x2 y2 . . . ) Da das Programm (bisher) davon ausgeht, daß alle Struktureinheiten nach line Zahlen enthalen, gibt es natürlich bei den Sonderausdrücken Fehlermeldungen. Daher sucht mein Freund eine Möglichkeit zu prüfen, ob einer Variable eine Zahl oder ein String zugewiesen wurde. Danke ! tschuess Marco.
On 19-Jun-2001, Duck (Marco Wenzel) wrote:
Hallo,
es ist OT und deshalb bitte Antwort per PM an steiger@web.de:
nicht wirklich. Perl gehoert zu Unix.
Mein Freund sucht eine Möglichkeit in Perl zu unterscheiden, ob eine Variable einen Zahlenwert oder ein Wort enthält.
if ($variable =~ /\d+/) { print $variable, "is eine Zahl\n"; } elsif ($variable =~ /\w+/) { print $variable "ist ein Wort\n"; } Gruss, Oliver
Hi, On Tue, Jun 19 2001 at 07:18 +0200, Oliver Kiehl wrote:
On 19-Jun-2001, Duck (Marco Wenzel) wrote:
Mein Freund sucht eine Möglichkeit in Perl zu unterscheiden, ob eine Variable einen Zahlenwert oder ein Wort enthält.
if ($variable =~ /\d+/) { print $variable, "is eine Zahl\n"; } elsif ($variable =~ /\w+/) { print $variable "ist ein Wort\n"; }
Damit wird jeder String, in dem mindestens eine Ziffer vorkommt, als Zahl erkannt, z.B. auch "a1b". Falls die Zahlen keine Kommas, Punkte oder Vorzeichen enthalten, wäre if ($variable =~ /^\d+$/) sinnvoll. Ciao, Stefan -- Stefan Troeger o _ _ _ stefan@troeger.st __o __o /\_ _ \\o (_)\__/o (_) _`\<, _`\<, _>(_) (_)/<_ \_| \ _|/' \/ (_)/(_) (_)/(_) (_) (_) (_) (_)' _\o_
On Die, Jun 19, 2001 at 09:18:03 +0200, Stefan Troeger wrote:
On Tue, Jun 19 2001 at 07:18 +0200, Oliver Kiehl wrote:
On 19-Jun-2001, Duck (Marco Wenzel) wrote:
Mein Freund sucht eine Möglichkeit in Perl zu unterscheiden, ob eine Variable einen Zahlenwert oder ein Wort enthält.
if ($variable =~ /\d+/) { print $variable, "is eine Zahl\n"; } elsif ($variable =~ /\w+/) { print $variable "ist ein Wort\n"; }
Damit wird jeder String, in dem mindestens eine Ziffer vorkommt, als Zahl erkannt, z.B. auch "a1b". Falls die Zahlen keine Kommas, Punkte oder Vorzeichen enthalten, wäre
if ($variable =~ /^\d+$/)
sinnvoll.
$is_num = ( $variable =~ /^\d*[.,]?\d+$/ ); berücksichtigt auch Punkt und Komma. Jan
>>>>>>>>>>>> Original Message <<<<<<<<<<<<<<<<<<
On 19.06.01, 10:38:32, Jan.Trippler@t-online.de (Jan Trippler) wrote regarding re ot perl variablen-unterscheidung@3:
On Die, Jun 19, 2001 at 09:18:03 +0200, Stefan Troeger wrote:
On Tue, Jun 19 2001 at 07:18 +0200, Oliver Kiehl wrote:
On 19-Jun-2001, Duck (Marco Wenzel) wrote:
Mein Freund sucht eine Möglichkeit in Perl zu unterscheiden, ob eine Variable einen Zahlenwert oder ein Wort enthält.
if ($variable =~ /\d+/) { print $variable, "is eine Zahl\n"; } elsif ($variable =~ /\w+/) { print $variable "ist ein Wort\n"; }
Damit wird jeder String, in dem mindestens eine Ziffer vorkommt, als Zahl erkannt, z.B. auch "a1b". Falls die Zahlen keine Kommas, Punkte oder Vorzeichen enthalten, wäre
if ($variable =~ /^\d+$/)
sinnvoll.
$is_num = ( $variable =~ /^\d*[.,]?\d+$/ );
berücksichtigt auch Punkt und Komma.
Found in usr/lib/perl5/5.6.0/pod/perlfaq4.pod How do I determine whether a scalar is a number/whole/integer/float? Assuming that you don't care about IEEE notations like "NaN" or "Infinity", you probably just want to use a regular expression. if (/\D/) { print "has nondigits\n" } if (/^\d+$/) { print "is a whole number\n" } if (/^-?\d+$/) { print "is an integer\n" } if (/^[+-]?\d+$/) { print "is a +/- integer\n" } if (/^-?\d+\.?\d*$/) { print "is a real number\n" } if (/^-?(?:\d+(?:\.\d*)?|\.\d+)$/) { print "is a decimal number" } if (/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/) { print "a C float" } If you're on a POSIX system, Perl's supports the `POSIX::strtod' function. Its semantics are somewhat cumbersome, so here's a `getnum' wrapper function for more convenient access. This function takes a string and returns the number it found, or `undef' for input that isn't a C float. The `is_numeric' function is a front end to `getnum' if you just want to say, ``Is this a float?'' sub getnum { use POSIX qw(strtod); my $str = shift; $str =~ s/^\s+//; $str =~ s/\s+$//; $! = 0; my($num, $unparsed) = strtod($str); if (($str eq '') || ($unparsed != 0) || $!) { return undef; } else { return $num; } } sub is_numeric { defined getnum($_[0]) } Or you could check out the String::Scanf module on CPAN instead. The POSIX module (part of the standard Perl distribution) provides the `strtol' and `strtod' for converting strings to double and longs, respectively. Greets Florian
On Die, Jun 19, 2001 at 07:32:53 +0000, Florian Brunner wrote:
>>>>>>>>>>>>> Original Message <<<<<<<<<<<<<<<<<< *urrks*
On 19.06.01, 10:38:32, Jan.Trippler@t-online.de (Jan Trippler) wrote regarding re ot perl variablen-unterscheidung@3:
steht eigentlich schon im Subject (allerdings ein wenig merkwürdig formatiert - meine mutt-Konfiguration kann das nicht dem Thread zuordnen :-(). [Ausschnitte aus Perl-FAQ]
if (/^-?(?:\d+(?:\.\d*)?|\.\d+)$/) { print "is a decimal
Interessant, aber ich sehe bei dem Konstrukt ?: nicht durch. Kann das jemand erklären? In meinen Büchlein habe ich dazu nix gefunden. Die Funktion eines ? ist mir schon klar, aber in der o. g. Konstellation kann ich mit diesem Muster nichts anfangen. :-( Was ist der Unterschied in der Mustererkennung zu: /^[+-]?\d*[.,]?\d+$/ (von der Erkennung des Kommas abgesehen, die Vorzeichenerkennung habe ich einfach mal ergänzt)? Jan
Hi, On Tue, Jun 19 2001 at 21:38 +0200, Jan Trippler wrote:
On Die, Jun 19, 2001 at 07:32:53 +0000, Florian Brunner wrote:
[Ausschnitte aus Perl-FAQ]
if (/^-?(?:\d+(?:\.\d*)?|\.\d+)$/) { print "is a decimal
Interessant, aber ich sehe bei dem Konstrukt ?: nicht durch. Kann das jemand erklären? In meinen Büchlein habe ich dazu nix gefunden. Die Funktion eines ? ist mir schon klar, aber in der o. g. Konstellation kann ich mit diesem Muster nichts anfangen. :-(
(?: ) dient wie ( ) zur Gruppierung, speichert aber nichts in den Variablen $1, $2 usw.
Was ist der Unterschied in der Mustererkennung zu: /^[+-]?\d*[.,]?\d+$/ (von der Erkennung des Kommas abgesehen, die Vorzeichenerkennung habe ich einfach mal ergänzt)?
Der Regex aus der FAQ passt auch auf Zahlen, die mit einem Punkt enden (1.), ansonsten scheint da kein riesiger Unterschied zu sein. Ciao, Stefan -- Stefan Troeger o _ _ _ stefan@troeger.st __o __o /\_ _ \\o (_)\__/o (_) _`\<, _`\<, _>(_) (_)/<_ \_| \ _|/' \/ (_)/(_) (_)/(_) (_) (_) (_) (_)' _\o_
>>>>>>>>>>>> Original Message <<<<<<<<<<<<<<<<<<
On 19.06.01, 22:25:05, Stefan Troeger
Hi,
On Tue, Jun 19 2001 at 21:38 +0200, Jan Trippler wrote:
On Die, Jun 19, 2001 at 07:32:53 +0000, Florian Brunner wrote:
[Ausschnitte aus Perl-FAQ]
if (/^-?(?:\d+(?:\.\d*)?|\.\d+)$/) { print "is a decimal
Interessant, aber ich sehe bei dem Konstrukt ?: nicht durch. Kann das jemand erklären? In meinen Büchlein habe ich dazu nix gefunden. Die Funktion eines ? ist mir schon klar, aber in der o. g. Konstellation kann ich mit diesem Muster nichts anfangen. :-(
(?: ) dient wie ( ) zur Gruppierung, speichert aber nichts in den Variablen $1, $2 usw.
Was ist der Unterschied in der Mustererkennung zu: /^[+-]?\d*[.,]?\d+$/ (von der Erkennung des Kommas abgesehen, die Vorzeichenerkennung habe ich einfach mal ergänzt)?
Der Regex aus der FAQ passt auch auf Zahlen, die mit einem Punkt enden (1.), ansonsten scheint da kein riesiger Unterschied zu sein.
Und vor allem auch auf Zahlen wie '.5', wenn ich den Ausdruck recht verstehe. Der Ausdruck besagt passt also auf alle Zahlen, die max. 1 Punkt und optional ein '-' als Vorzeichen haben. Beachte auch, dass '.' escaped werden muss ('.' ist ja ein Sonderzeichen in Regexp) (oder ist das bei eckigen Klammern anders - denke nicht?) Wie wärs z.B. mit folgendem Ausdruck: /^[\+-]?(?:\d+(?:[\.\,]\d*)?|[\.\,]\d+)$/ - muss ',' und '+' escaped werden? Wird wohl nicht schaden... Greets Florian
On Die, Jun 19, 2001 at 10:11:04 +0000, Florian Brunner wrote:
On 19.06.01, 22:25:05, Stefan Troeger
wrote: On Tue, Jun 19 2001 at 21:38 +0200, Jan Trippler wrote:
On Die, Jun 19, 2001 at 07:32:53 +0000, Florian Brunner wrote: [Ausschnitte aus Perl-FAQ]
if (/^-?(?:\d+(?:\.\d*)?|\.\d+)$/) { print "is a decimal
[...] Was ist der Unterschied in der Mustererkennung zu: /^[+-]?\d*[.,]?\d+$/ (von der Erkennung des Kommas abgesehen, die Vorzeichenerkennung habe ich einfach mal ergänzt)?
Der Regex aus der FAQ passt auch auf Zahlen, die mit einem Punkt enden (1.), ansonsten scheint da kein riesiger Unterschied zu sein.
Und vor allem auch auf Zahlen wie '.5', wenn ich den Ausdruck recht verstehe.
Das kann der von mir gepostete auch (\d* am Anfang sorgt dafür). Entscheidend ist der Umstand, dass sowohl 1. als auch .1 erfasst werden. Dann muss das Muster zwangsläufig komplexer aussehen.
Der Ausdruck besagt passt also auf alle Zahlen, die max. 1 Punkt und optional ein '-' als Vorzeichen haben.
Das ist nur die halbe Miete. Es muss mindestens eine Ziffer enthalten sein, das macht den Ausdruck so wüst ;-)
Beachte auch, dass '.' escaped werden muss ('.' ist ja ein Sonderzeichen in Regexp) (oder ist das bei eckigen Klammern anders - denke nicht?)
Denke doch - probiers aus.
Wie wärs z.B. mit folgendem Ausdruck: /^[\+-]?(?:\d+(?:[\.\,]\d*)?|[\.\,]\d+)$/ - muss ',' und '+' escaped werden? Wird wohl nicht schaden...
Das Entwerten macht den Ausdruck unübersichtlicher und ist in [] (bei den meisten Zeichen) unnötig. Also sollte es: /^[+-]?(?:\d+(?:[.,]\d*)?|[.,]\d+)$/ auch tun (ungetestet, ich bin müde ;-) Hier gibt es aber einen lästigen Effekt: Die Verwendung von . und , in der gleichen Zahl ist hier zulässig - was natürlich nicht im Sinne des Erfinders sein kann. Sowas sollte man vielleicht besser vorher abfangen oder aber den Dezimaltrenner per Variable übergeben. Jan
Hi, On Tue, Jun 19 2001 at 22:11 +0000, Florian Brunner wrote:
Beachte auch, dass '.' escaped werden muss ('.' ist ja ein Sonderzeichen in Regexp) (oder ist das bei eckigen Klammern anders - denke nicht?)
In eckigen Klammern muss man den Punkt nicht escapen (was für ein Wort), es schadet aber auch nicht.
Wie wärs z.B. mit folgendem Ausdruck: /^[\+-]?(?:\d+(?:[\.\,]\d*)?|[\.\,]\d+)$/ - muss ',' und '+' escaped werden? Wird wohl nicht schaden...
In [ ] ist es bei beiden nicht nötig; außerhalb nur beim Plus, beim Komma ist es egal (, und \, sind gleichwertig). Ciao, Stefan -- Stefan Troeger o _ _ _ stefan@troeger.st __o __o /\_ _ \\o (_)\__/o (_) _`\<, _`\<, _>(_) (_)/<_ \_| \ _|/' \/ (_)/(_) (_)/(_) (_) (_) (_) (_)' _\o_
Hallo, Jan Trippler wrote:
$is_num = ( $variable =~ /^\d*[.,]?\d+$/ );
berücksichtigt auch Punkt und Komma.
Wie waere es mit $is_zahl = ($variable * 1) == $variable Das beruecksichtigt alle Moeglichkeiten, auch komplexe Zahlen. :-) Das durfte zumindest schneller sein, als eine RegEx. Jan -- ETES - Espenhain & Theofel EDV-Systemhaus GbR Libanonstrasse 58 A * D-70184 Stuttgart Phone +49 711 4895550 * Fax +49 711 4809761 EMail: info@etes.de --- URL: www.etes.de
Hi, On Tue, Jun 19 2001 at 22:19 +0200, Jan Theofel wrote:
Wie waere es mit $is_zahl = ($variable * 1) == $variable
Ungünstig. Wenn man in Perl einen String, der nicht mit einer Zahl beginnt, als Zahl zu verwenden versucht, wird er stillschweigend in 0 umgewandelt, und diese erfüllt dann den obigen Test: [sttr]/home/sttr> perl -le '$var = "abc"; print $var * 1 == $var' 1 Ciao, Stefan -- Stefan Troeger o _ _ _ stefan@troeger.st __o __o /\_ _ \\o (_)\__/o (_) _`\<, _`\<, _>(_) (_)/<_ \_| \ _|/' \/ (_)/(_) (_)/(_) (_) (_) (_) (_)' _\o_
Am Die, 19 Jun 2001, schrieb Jan Theofel:
Hallo,
Jan Trippler wrote:
$is_num = ( $variable =~ /^\d*[.,]?\d+$/ );
berücksichtigt auch Punkt und Komma.
Wie waere es mit $is_zahl = ($variable * 1) == $variable
Das beruecksichtigt alle Moeglichkeiten, auch komplexe Zahlen. :-)
Folgendes habe ich zufällig gestern im Perl Cookbook gefunden -----schnipp------ 2.1 Checking wether a string is a valid number [Da werden dann einige Dinge erzählt und letztendlich RegEx-Patterns angegeben] [...] warn "not a decimal number" unless /^-?(?:\d+(?:\.\d*)?|\.\d+))?$/; -----schnappp----- Gruß Christoph -- Christoph Maurer - Paul-Röntgen-Straße 7 - 52072 Aachen - Tux#194235 mailto:christoph-maurer@gmx.de - http://www.christophmaurer.de Auf der Homepage u.a.: Installation von SuSE 7.0 auf Notebook Acer Travelmate 508 T, Elektrotechnik an der RWTH Aachen
On Mit, Jun 20, 2001 at 09:47:53 +0200, Christoph Maurer wrote:
Am Die, 19 Jun 2001, schrieb Jan Theofel:
Jan Trippler wrote:
$is_num = ( $variable =~ /^\d*[.,]?\d+$/ );
berücksichtigt auch Punkt und Komma.
Wie waere es mit $is_zahl = ($variable * 1) == $variable
Das beruecksichtigt alle Moeglichkeiten, auch komplexe Zahlen. :-)
Folgendes habe ich zufällig gestern im Perl Cookbook gefunden [...] warn "not a decimal number" unless /^-?(?:\d+(?:\.\d*)?|\.\d+))?$/;
Diese Variante kam schon im anderen Teilthread (der Thread ist leider durch ungeschickte Subject-Reformatierung zerrupft worden :-() Was hier noch zu berücksichtigen war: - Zahlen, die mit einem + beginnen, werden nicht erfasst (kann durch /^[+-]? usw. gelöst werden) - Das Komma als Dezimaltrenner wird nicht akzeptiert - hier müsste man entweder mit einer Variablen arbeiten oder vorher umwandeln (Umwandeln ist sicher am besten, wenn man das weiter in Perl verarbeiten will, da Perl nur den Punkt akzeptiert) Jan
Hallo Leute, vielen Dank für eure Tips. Mein Freund wird sich jetzt da durchackern. Tschuess Marco.
participants (7)
-
Christoph Maurer
-
Duck (Marco Wenzel)
-
Florian Brunner
-
Jan Theofel
-
Jan.Trippler@t-online.de
-
Oliver Kiehl
-
Stefan Troeger