Thomas: Entfernen nur vor bestimmten Zeichen

Hallo,

ich habe Strings in der Form

"wort wort 12345"

und möchte nur das Leerzeichen vor der Zahl entfernen.
Bei substitute und transliterate werden je nach Muster
aber entweder alle Leerzeichen entfernt oder das Leerzeichen
mit der ersten Zahl.

$string =~ s/ [0-9]/[0-9]/g;

Wie lautet das Muster richtig?

  1. gudn tach!

    ich habe Strings in der Form

    "wort wort 12345"

    und möchte nur das Leerzeichen vor der Zahl entfernen.

    $string =~ s/ [0-9]/[0-9]/g;

    Wie lautet das Muster richtig?

    $string =~ s/ ([0-9]+)$/$1/;

    perldoc perlre erklaert das plus, die klammern und das erste dollar und das zweite dollar mit der 1.

    prost
    seth

    1. danke!

      jetzt habe ich "wort12345".
      Mit welchem Ausdruck bekomme ich den Blank wieder dazwischen?

      (Das ganze dient dem Schutz der "Wort-Leerzeichen-Zahl"-Kombination vor split an jedem Blank.)

      1. gudn tach!

        jetzt habe ich "wort12345".

        Mit welchem Ausdruck bekomme ich den Blank wieder dazwischen?

        aeh... du wolltest es doch gerade killen...

        mit $string =~ s/ ([0-9]+)$/$1/; isses weg.
        mit $string =~ s/([a-zA-Z])([0-9]+)$/$1 $2/; (oder $string =~ s/(?<=[a-zA-Z])([0-9]+)$/ $1/;) isses wieder da.

        man koennte beide schritte auch zusammenfassen zu
        $string =~ s/([a-zA-Z]) ?([0-9]+)$/$1 $2/;

        erklaerung wieder via perldoc perlre.

        prost
        seth

        1. Super! Vielen Dank für die Hilfe!

          1. Noch ein weiteres Problem:
            Wenn ich den "Kill-Blank"-Ausdruck ein weiteres Mal anwende, wird er nicht mehr ausgeführt. Hier mal das ganze Ding:

            <IN1>:
            Hotspot 180
            Jahr 2000

            <IN2>:
            N = Hotspot 180 ':hotspot_180', Jahr 2000 ':jahr_2000',

            (...)
            while(chomp($line=<IN1>)){
            $line=lc($line);

            Kill-Blank zum Ersten:

            $line=~s/ ([0-9]+)$/$1/g;

            $line=~tr/^!"§$%&/()=?´`*+'#,;.:_<>|@~\{}[]/ /;
            @target=split/ +/,$line;
            push(@query,@target);}

            Feed-Blank zum Ersten:

            foreach (@query){
            $_=~s/([a-z])([0-9]+)$/$1 $2/;}

            @query=sort(@query);

            Warum geht hier kein chomp in der Klammer? (-> Sighup)

            while($line=<IN2>){
            $line=lc($line);

            Kill-Blank zum Zweiten (!!!Hier funzt es nicht!!!):

            $line=~s/ ([0-9]+)$/$1/g;

            @target=split/ /,$line;

            Feed-Blank zum Zweiten:

            foreach (@target){
            $_=~s/([a-z])([0-9]+)$/$1 $2/;}
            push(@dict1,@target);
            }

            Der "Kill-Blank"-Ausdruck ist beide Male genau gleich. Wieso bewirkt er beim zweiten Mal keine Änderung?

            1. gudn tach!

              <IN1>:
              Hotspot 180
              Jahr 2000

              <IN2>:
              N = Hotspot 180 ':hotspot_180', Jahr 2000 ':jahr_2000',

              while(chomp($line=<IN1>)){ [...]

              <http://perldoc.perl.org/perlop.html#I%2fO-Operators-operator%2c-i%2fo-operator%2c-io-io-while-filehandle-%3c%3e-%40ARGV@perldoc perlop>:
              "In scalar context, evaluating a filehandle in angle brackets yields the next line from that file (the newline, if any, included), or undef at end-of-file or on error."

              also:

              while($line=<IN1>){  
               chomp($line);  
               # [...]
              

              Warum geht hier kein chomp in der Klammer?

              es sollte aus den eben genannten gruenden auch oben nicht gehen.

              Kill-Blank zum Zweiten (!!!Hier funzt es nicht!!!):

              $line=~s/ ([0-9]+)$/$1/g;

              was funzt nicht?
              hast du (in den von mir verlinkten dokumenten) nachgelesen, was die einzelnen symbole bedeuten?

              prost
              seth

              1. hallo,

                was funzt nicht?
                hast du (in den von mir verlinkten dokumenten) nachgelesen, was
                die einzelnen symbole bedeuten?

                gelesen ja, aber immer noch nicht so richtig verstanden.
                Wenn ich $line=~s/ ([0-9]+)$/$1/g; beim zweiten Mal anwende,
                bleibt die $line unverändert.
                Da sollte jetzt eigentlich auch "(...) hotspot180 (...)" stehen,
                es steht aber immer noch "(...) hotspot 180 (...)" drin.

                1. gudn tach!

                  was funzt nicht?
                  hast du (in den von mir verlinkten dokumenten) nachgelesen, was
                  die einzelnen symbole bedeuten?

                  gelesen ja, aber immer noch nicht so richtig verstanden.

                  bei welchen zeichen hakt's denn noch?
                  nimm s/ ([0-9]+)$/$1/g komplett auseinander, z.b. auf papier und ueberlege was jeder bestandteil bedeutet.
                  das was du nicht verstehst, schlaegst du einfach z.b. in perldoc perlre, perldoc perlrequick oder perldoc perlretut nach, z.b. nach "$/" (ohne die anfuehrungszeichen).

                  vielleicht hilft dir hier auch selfhtml weiter. vor allem beispiel 18 und 19 und die darunter folgende erklaerung.

                  Wenn ich $line=~s/ ([0-9]+)$/$1/g; beim zweiten Mal anwende,
                  bleibt die $line unverändert.

                  ja.

                  Da sollte jetzt eigentlich auch "(...) hotspot180 (...)" stehen,
                                                                   ^^^^^^

                  ist nicht $

                  prost
                  seth

                2. Ah, doch
                  jetzt hab ichs verstanden. Das Dollar nach der Klammer muss weg, da die Zahl ja nicht am Ende steht.

                  1. gudn tach!

                    jetzt hab ichs verstanden. Das Dollar nach der Klammer muss weg, da die Zahl ja nicht am Ende steht.

                    rischdisch. :-)
                    bleibt noch anzumerken, dass

                    s/ ([0-9]+)/$1/g

                    oder kuerzer (denn [0-9] ist dasselbe wie \d)

                    s/ (\d+)/$1/g

                    oooder noch kuerzer (denn es soll ja bloss mind. eine ziffer folgen)

                    s/ (\d)/$1/g

                    oder genauso kurz, aber anders formuliert

                    s/ (?=\d)//g

                    z.b. folgendes tun wuerde:
                       "foo 42 bar 13 baz"
                    -> "foo42 bar13 baz"

                    "foo 42bar 13 baz"
                    -> "foo42bar13 baz"

                    "foo 4 2 bar"
                    -> "foo42bar"

                    (ich weiss nicht, ob du diese ersetzungen alle haben willst oder ob sie probleme machen koennten, deswegen sage ich es bloss sicherheitshalber mal dazu.)

                    prost
                    seth

                    1. Alles klar,
                      jetzt funktioniert es, wie es soll.
                      Nochmal vielen Dank!