joha: split

Vielleicht bin ich ja blind und blöd zugleich, ich habe nämlich ein sehr einfaches, kleines Problem!

Ich möchte zum beispiel Dorfstrasse17 splitten und zwar vor der zahl, dort hat es aber keinen lehrschlag oder sonst einen Anhaltspunkt..
sonst könnte man ganz einfach

my $wohnort (also Dorfstrasse17)
my @adresse = split(/ /,$wohnort);

eingeben, es gibt sicher etwas ähnliches für die trennung von Zahlen und Buchstaben, oder?

cu joha

  1. Hallo Joha,

    my $wohnort (also Dorfstrasse17)
    my @adresse = split(/ /,$wohnort);
    eingeben, es gibt sicher etwas ähnliches für die trennung von Zahlen und Buchstaben, oder?

    Nicht dass ich wuesste. Bei split() braucht man nun mal irgendein Zeichen oder eine Zeichenfolge, die als Separator dient. Wo aber nix ist, kann auch nix separieren.
    "Dorfstrasse17" ist ja auch nicht gerade korrekt. Wenn da z.B. "Dorfstr.17" stehen wuerde, koenntest du den Punkt nehmen - was allerdings bei Anschriften wie "Dr.Julius-Leber-Str." zu unerwuenschtem Splitting fuehrt ...

    viele Gruesse
      Stefan Muenz

    1. hi!

      Nicht dass ich wuesste. Bei split() braucht man nun mal irgendein
      Zeichen oder eine Zeichenfolge, die als Separator dient. Wo aber nix
      ist, kann auch nix separieren.

      Nee, braucht man nicht, denn Perls reguläre Ausdrücke haben den
      Vorteil, dass sie keine "echten" regulären Ausdrücke sind... ;))

      Jedenfalls beherrschen die regulären Ausdrücke in Perl so Features wie
      Backtracking und "look ahead"- bzw. "look behind"-Anweisungen, mit
      denen man einige nette Dinge tun kann, wenn man sich damit auskennt...

      bye, Frank!

  2. Hoi,  <-- Begruessung

    Ich möchte zum beispiel Dorfstrasse17 splitten und zwar vor der zahl, dort hat es aber keinen
    lehrschlag oder sonst einen Anhaltspunkt..
    sonst könnte man ganz einfach

    my $wohnort (also Dorfstrasse17)
    my @adresse = split(/ /,$wohnort);

    eingeben, es gibt sicher etwas ähnliches für die trennung von Zahlen und Buchstaben, oder?

    Es gibt kein Split dafuer. Aber die Loesung laesst sich mit einem RegEx ganz einfach schreiben:

    my ($strasse,$nummer) = $wohnort =~ m/^([^0-9]+)([0-9]+)$/i;

    Zur Erklaerung: der RegEx schaut, ob der String mit etwas anderem als einer Zahl beginnt,
    speichert das und schaut dann, ob der String mit einer Zahl endet und speichert diese auch.

    Mehr Infos dazu gibts in

    perldoc perlre
    perldoc perlfunc
    perldoc perlop

    Gruesse,
     CK

    1. Es gibt kein Split dafuer. Aber die Loesung laesst sich mit einem RegEx ganz einfach schreiben:

      Doch ;-)

      Fuer die Hausnummer:
      @kk = split ( /[a-zA-Z]/, $wohnort );

      Fuer die Strasse:
      @kk = split ( /[0-9]/, $wohnort );

      Gruß
      Jürgen Schneider

    2. Hallo,

      my $wohnort (also Dorfstrasse17)
      my @adresse = split(/ /,$wohnort);

      eingeben, es gibt sicher etwas ähnliches für die trennung von Zahlen und Buchstaben, oder?

      Es gibt kein Split dafuer.

      Naja, eigentlich schon, aber 'patschert' ist es trotzdem:

      ($straße,$hausnummer) = split(/\s*([0-9]+)/,$wohnort,2);

      siehe dazu perldoc -f split (Absatz beginnend mit 'If the PATTERN contains parentheses').

      Grüße
        Klaus

      1. hi!

        Naja, eigentlich schon, aber 'patschert' ist es trotzdem:
        ($straße,$hausnummer) = split(/\s*([0-9]+)/,$wohnort,2);

        Hm, ich würde ein "look ahead"-Pattern dafür verwenden. Dann hat man
        den Nachteil der Spezial-Bedeutung von Klammern bei split() umgangen,
        indem man ein Standard-Feature der regulären Ausdrücke von Perl
        verwendet. Würde dann so aussehen:

        ($straße, $hausnummer) = split /(?=[0-9])/, $wohnort, 2;

        Das bedeutet, _vor_ jedem Vorkommen einer Ziffer wird aufgesplittet,
        ohne die Ziffer selbst als Separator zu betrachten.

        bye, Frank!

        1. Hoi,

          Naja, eigentlich schon, aber 'patschert' ist es trotzdem:
          ($straße,$hausnummer) = split(/\s*([0-9]+)/,$wohnort,2);

          [...]

          ($straße, $hausnummer) = split /(?=[0-9])/, $wohnort, 2;

          Hui, das ist interessant. Der Algorithmus ist sehr schnell:

          #!/usr/bin/perl -w

          use strict;
          use Benchmark;

          timethese(1000000,
                    {
                     regex => sub {
                                   my $wohnort = 'Dorfstrasse17';
                                   my ($str,$hnr) = $wohnort =~ m/^([^0-9]+)([0-9]+)$/;
                                  },
                     splt1 => sub {
                                   my $wohnort = 'Dorfstrasse17';
                                   @kk = split(/[a-z]/i,$wohnort);
                                   @kk = split(/[0-9]/,$wohnort);
                                  },
                     splt2 => sub {
                                   my $wohnort = 'Dorfstrasse17';
                                   my ($str,$hnr) = split(/\s*([0-9]+)/,$wohnort,2);
                                  },
                     splt3 => sub {
                                   my $wohnort = 'Dorfstrasse17';
                                   my ($str,$hnr) = split(/(?=[0-9])/, $wohnort, 2);
                                  }
                    }
                   );

          eof

          H:\Perl\bin>perl bench.pl
          Benchmark: timing 1000000 iterations of regex, splt1, splt2, splt3...
               regex:  6 wallclock secs ( 5.16 usr +  0.00 sys =  5.16 CPU) @ 193836.01/s (n=1000000)
               splt1: 15 wallclock secs (15.05 usr +  0.02 sys = 15.07 CPU) @ 66343.79/s (n=1000000)
               splt2: 10 wallclock secs ( 9.06 usr +  0.00 sys =  9.06 CPU) @ 110326.57/s (n=1000000)
               splt3:  6 wallclock secs ( 5.63 usr +  0.00 sys =  5.63 CPU) @ 177683.01/s (n=1000000)

          H:\Perl\bin>

          1. Hallo,

            Hui, das ist interessant. Der Algorithmus ist sehr schnell:

            Und wenn man ein bißchen herumspielt, geht's auch noch hurtiger;-)
            splt1 habe ich weggelassen, weil es IMHO keine vernünftigen Ergebnisse liefert.
            regex2, splt2b liefert die gleichen Ergebnisse wie splt3, d.h. auch Nummern wie 17a werden erkannt.
            splt2a entfernt auch noch die Leerzeichen zwischen Straße und Nummer, wie es grundsätzlich auch splt2 tun würde, welches allerdings nicht richtig bei 17a arbeitet.

            timethese(1000000,
                      {
                       regex => sub {
                                     my $wohnort = 'Dorfstrasse17';
                                     my ($str,$hnr) = $wohnort =~ m/^([^0-9]+)([0-9]+)$/;
                                    },
                       regex2 => sub {
                                     my $wohnort = 'Dorfstrasse17';
                                     my ($str,$hnr) = $wohnort =~ m/^([^0-9]+)([0-9].*)$/;
                                    },
                       splt2 => sub {
                                     my $wohnort = 'Dorfstrasse17';
                                     my ($str,$hnr) = split(/\s*([0-9]+)/,$wohnort);
                                    },
                       splt2a => sub {
                                     my $wohnort = 'Dorfstrasse17';
                                     my ($str,$hnr) = split(/\s*([0-9].*)/,$wohnort);
                                    },
                       splt2b => sub {
                                     my $wohnort = 'Dorfstrasse17';
                                     my ($str,$hnr) = split(/([0-9].*)/,$wohnort);
                                    },
                       splt3 => sub {
                                     my $wohnort = 'Dorfstrasse17';
                                     my ($str,$hnr) = split(/(?=[0-9])/, $wohnort, 2);
                                    }
                      }
                     );

            Benchmark: timing 1000000 iterations of regex, regex2, splt2, splt2a, splt2b, splt3...
                 regex:  7 wallclock secs ( 7.29 usr +  0.00 sys =  7.29 CPU) @ 137155.40/s (n=1000000)
                regex2:  9 wallclock secs ( 7.56 usr +  0.00 sys =  7.56 CPU) @ 132257.64/s (n=1000000)
                 splt2: 13 wallclock secs (12.16 usr +  0.01 sys = 12.17 CPU) @ 82196.28/s (n=1000000)
                splt2a:  7 wallclock secs ( 7.60 usr +  0.00 sys =  7.60 CPU) @ 131578.95/s (n=1000000)
                splt2b:  7 wallclock secs ( 7.32 usr +  0.00 sys =  7.32 CPU) @ 136593.36/s (n=1000000)
                 splt3:  9 wallclock secs ( 8.46 usr +  0.00 sys =  8.46 CPU) @ 118161.41/s (n=1000000)

            Ach ja, und alle haben Schwierigkeiten mit 'Platz des 4.Oktober 15';-)

            Grüße
              Klaus

  3. Danke, ihr konntet mir wirklich unter die Arme greifen! ;-)

    Grüsse Joha