Announcement

Collapse
No announcement yet.

Teilstring finden

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Teilstring finden

    Hi Leute, <BR><BR>
    ich möchte aus einem String die Position des ersten Leerzeichen herausfinden (Ich weiss mit Pos(' ', StringVAR) ;-)) kann ich irgendwie den Suchstring genauer mit und bzw. oder ergänzen? Ich möchte aus der Variabele StringVAR die Position des ersten Leerzeichen, jedoch nicht wenn auf dem Leerzeichen ein '\' folgt z.B.:<br><br>
    'abcdedf \abdcdefg asdlkfja' = 18<br><br>
    Geht das mit POS bzw einer anderen Funktion oder muss ich mir da selber was basteln?<br><BR>
    Danke CU

  • #2
    mach doch einfach zwei pos abfragen. einmal mit ' ' und das anderemal mit ' \'. ist der wert von pos gleich, folgt auf das leerzeichen ein '\

    Comment


    • #3
      @patrick

      den gedanken hatte ich auch schon, allerdings löst das nicht das problem. die sache ist etwas komplexer.
      um zum ersten alleinstehenden ' ' zu kommen muss man zur not den string zerteilen, sich die jeweiligen teilstringgrössen merken, bis pos(' ',s) <>pos(' \',s) ist.
      anschliessend pos + teilstringgröße1 + ... teilstringgröße n

      also etwas aufwendiger als es den anschein hat. ich lass mich aber auch gern eines besseren belehren.

      ciao

      swe

      Comment


      • #4
        Hallo

        So aufwendig ist es nicht

        function SuperFind(const S : string) : integer;
        var L,I : integer;
        begin
        L:=Length(S);
        for I=1 to L do
        if S[I]=' ' and ((I=L) or (S[I+1]<>'/')) then begin
        Result:=I;
        Break;
        end;
        end;

        Mfg,

        Leonid Kandyb

        Comment


        • #5
          @ Leonid,<p>
          sorry mit mir ist Softwaretester durchgegangen und ich habe mir die Mühe gemacht deine Routine auf Herz
          und Nieren zu prüfen.<br>
          Du hast deine Routine sicherlich direkt hier ins Forum reingehackt, denn sie enthält schon mal 2
          Syntax-Fehler. Damit sie compliliert müßte sie wahrscheinlich so lauten:<PRE>
          function SuperFind(const S: String): Integer;
          var
          L,I: Integer;
          begin
          L := Length(S);
          for I := 1 to L do
          if (S[I] = ' ') and ((I = L) or (S[I+1] <> '/')) then begin
          Result := I;
          Break;
          end;
          end;</PRE>
          Aber selbst so tut sie noch lange nicht so wie sie soll: Hier meine Testfälle:<PRE>
          procedure TForm1.FormActivate(Sender: TObject);
          begin
          OutputDebugString(PChar('Erwartet 0, geliefert: ' + IntToStr(SuperFind(''))));
          OutputDebugString(PChar('Erwartet 1, geliefert: ' + IntToStr(SuperFind(' '))));
          OutputDebugString(PChar('Erwartet 1, geliefert: ' + IntToStr(SuperFind(' '))));
          OutputDebugString(PChar('Erwartet 0, geliefert: ' + IntToStr(SuperFind('\'))));
          OutputDebugString(PChar('Erwartet 0, geliefert: ' + IntToStr(SuperFind(' \'))));
          OutputDebugString(PChar('Erwartet 2, geliefert: ' + IntToStr(SuperFind('\ '))));
          OutputDebugString(PChar('Erwartet 0, geliefert: ' + IntToStr(SuperFind('z'))));
          OutputDebugString(PChar('Erwartet 0, geliefert: ' + IntToStr(SuperFind('test\test'))));
          OutputDebugString(PChar('Erwartet 0, geliefert: ' + IntToStr(SuperFind('test \test'))));
          OutputDebugString(PChar('Erwartet 6, geliefert: ' + IntToStr(SuperFind('test\ test'))));
          OutputDebugString(PChar('Erwartet 7, geliefert: ' + IntToStr(SuperFind('test \ test'))));
          OutputDebugString(PChar('Erwartet 5, geliefert: ' + IntToStr(SuperFind('test \ test'))));
          OutputDebugString(PChar('Erwartet 0, geliefert: ' + IntToStr(SuperFind('test\ \test'))));
          OutputDebugString(PChar('Erwartet 8, geliefert: ' + IntToStr(SuperFind('test\ \ test'))));
          OutputDebugString(PChar('Erwartet 7, geliefert: ' + IntToStr(SuperFind('test \ test'))));
          OutputDebugString(PChar('Erwartet 0, geliefert: ' + IntToStr(SuperFind('test'))));
          OutputDebugString(PChar('Erwartet 0, geliefert: ' + IntToStr(SuperFind('test\'))));
          OutputDebugString(PChar('Erwartet 5, geliefert: ' + IntToStr(SuperFind('test '))));
          OutputDebugString(PChar('Erwartet 6, geliefert: ' + IntToStr(SuperFind('test\ '))));
          OutputDebugString(PChar('Erwartet 7, geliefert: ' + IntToStr(SuperFind('test \ '))));
          OutputDebugString(PChar('Erwartet 0, geliefert: ' + IntToStr(SuperFind('test\ \'))));
          OutputDebugString(PChar('Erwartet 8, geliefert: ' + IntToStr(SuperFind('test\ \ '))));
          OutputDebugString(PChar('Erwartet 6, geliefert: ' + IntToStr(SuperFind('test\ \ '))));
          OutputDebugString(PChar('Erwartet 18, geliefert: ' + IntToStr(SuperFind2('abcdedf \abdcdefg asdlkfja'))));
          end;</PRE>
          Fortsetzung folgt

          Comment


          • #6
            Fortsetzung<br>
            Und hier das Ergebnis aus dem Ereignisprotokoll-Fenster:<PRE>
            ODS: Erwartet 0, geliefert: 16 Prozess Project1.exe ($138)
            ODS: Erwartet 1, geliefert: 1 Prozess Project1.exe ($138)
            ODS: Erwartet 1, geliefert: 1 Prozess Project1.exe ($138)
            ODS: Erwartet 0, geliefert: -1 Prozess Project1.exe ($138)
            ODS: Erwartet 0, geliefert: 1 Prozess Project1.exe ($138)
            ODS: Erwartet 2, geliefert: 2 Prozess Project1.exe ($138)
            ODS: Erwartet 0, geliefert: -1 Prozess Project1.exe ($138)
            ODS: Erwartet 0, geliefert: -1 Prozess Project1.exe ($138)
            ODS: Erwartet 0, geliefert: 5 Prozess Project1.exe ($138)
            ODS: Erwartet 6, geliefert: 6 Prozess Project1.exe ($138)
            ODS: Erwartet 7, geliefert: 5 Prozess Project1.exe ($138)
            ODS: Erwartet 5, geliefert: 5 Prozess Project1.exe ($138)
            ODS: Erwartet 0, geliefert: 6 Prozess Project1.exe ($138)
            ODS: Erwartet 8, geliefert: 6 Prozess Project1.exe ($138)
            ODS: Erwartet 7, geliefert: 5 Prozess Project1.exe ($138)
            ODS: Erwartet 0, geliefert: -1 Prozess Project1.exe ($138)
            ODS: Erwartet 0, geliefert: -1 Prozess Project1.exe ($138)
            ODS: Erwartet 5, geliefert: 5 Prozess Project1.exe ($138)
            ODS: Erwartet 6, geliefert: 6 Prozess Project1.exe ($138)
            ODS: Erwartet 7, geliefert: 5 Prozess Project1.exe ($138)
            ODS: Erwartet 0, geliefert: 6 Prozess Project1.exe ($138)
            ODS: Erwartet 8, geliefert: 6 Prozess Project1.exe ($138)
            ODS: Erwartet 6, geliefert: 6 Prozess Project1.exe ($138)
            ODS: Erwartet 18, geliefert: 8 Prozess Project1.exe ($138)</PRE>
            Danach habe ich selber eine Routine (SuperFind2) geschrieben. Die sieht so aus:<PRE>
            { Falls kein Leerzeichen ohne nachfolgenden \ gefunden wird, so wird die
            Position := 0 zurückgeliefert.
            Ist im Prinzip ein endliches Automätchen mit 2 Zuständen.
            }
            function SuperFind2(const S: string): Integer;
            var
            BlankGefunden: Boolean;
            I: Integer;
            begin
            Result := 0;
            if (Length(S) > 0) then begin
            if S[1] = ' ' then begin
            BlankGefunden := True;
            end
            else begin
            BlankGefunden := False;
            end;
            I := 2;
            while I <= Length(S) do begin
            if BlankGefunden then begin
            if S[I] = '\' then begin
            BlankGefunden := False;
            end
            else begin
            Result := I - 1;
            Break;
            end;
            end
            else begin
            if S[I] = ' ' then begin
            BlankGefunden := True;
            end;
            end;
            Inc(I);
            end;
            if BlankGefunden and (Result = 0) then begin
            Result := I - 1;
            end;
            end;
            end;</PRE>
            Ist also etwas aufwendiger, als die von dir gedachte Funktion. Mein erster Entwurf der Routine hat
            natürlich meinen Test auch nicht erfolgreich durchlaufen. Ich mußte zweimal noch nachbessern. Ich wollte
            damit nur mal zeigen, daß selbst in Lösungen für solch trivialen Probleme schon etliche Fehlerteufelchen lauern.<p>
            @Frank<p>
            Meines Wissens nach gibt's keine fertige Lösung. Falls du in der Zwischenzeit keine eigene Lösung geschrieben hast, dann hast du jetzt zwei zur Auswahl.<p>
            Gruß<p>
            Wolfgang Roller<p>
            PS: Der Test ist auch nicht perfekt, sondern ähnlich schnell hingeschrieben, wie deine Routine. Trotzdem
            recht wirkungsvoll

            Comment


            • #7
              Hallo,
              Abgesehen von einigen Typefehler habe ich da ein Zeile vergessen
              Ganz am anfang der Routine solte "Result:=0;" stehen.
              Und Natürlich müsste "/" "\" heissen.(ich würde soetwas sowieso als Parameter übergeben)
              Sonst solte es funktionieren :-)
              Mfg

              Leonid Kandyb

              Comment


              • #8
                @Leonid<p>
                in der Tat, nach Beseitigung der Fehler sieht deine Routine so aus:<PRE>
                function SuperFind(const S: String): Integer;
                var
                L,I: Integer;
                begin
                Result := 0;
                L := Length(S);
                for I := 1 to L do
                if (S[I] = ' ') and ((I = L) or (S[I+1] <> '\')) then begin
                Result := I;
                Break;
                end;
                end;</PRE>
                und sie durchläuft den Test mit 0 Fehlern. Sieht so zugebenermaßen eleganter aus als meine Lösung. Aber einen kleinen Hacken hat deine Lösung noch: Man darf nicht den Compiler-Schalter {$B} (Boolesche Ausdrücke werden vollständig ausgewertet.) aktiviert haben. Ansonsten greift dein S[I+1] <> '\' unter Umständen übers Ziel hinaus.<p>
                Gruß<p>
                Wolfgang Rolle

                Comment


                • #9
                  {$B+} sollte niemals aktiviert werden, fast jeder gute Source den ich kenne nutzt unvollständige Boolsche Ausdrücke. Deshalb habe ich immer in meinen Source {$B-} gesetzt.

                  Gruß Hage

                  Comment

                  Working...
                  X