Lire une sous-chaine dans une chaine contenant des séparateurs.

Contenu du snippet

Soit une chaine contenant des sous-chaines séparées par un caractère. Comment récupérer la xième sous-chaine ?
Voir le code remanié après les contributions.

Source / Exemple :


function ChainePos(const Sep, Dans: String; const posi: cardinal = 1): String;
{fonction revisée par les commentateurs CodeSources comporte
- copie d'une fonction de l'unit sysuts "posex",
- retour d'une sous-chaine tirée d'une chaine selon séparateur et position entrés}

   //Déclaration
   function e_PosEx(const SubStr, S: string; Offset: Cardinal = 1): Integer;
     {renvoi le numero de position d'une chaine Substr dans une chaine S en scannant
     à partir de la position Offset}
     var I, X, Len, LenSubStr: Integer;
     begin
     if Offset = 1 then
        Result := Pos(SubStr,S)
     else
        begin
         I := Offset; LenSubStr := Length(SubStr);
         Len := Length(S)-LenSubStr+1;
         while I <= Len do
          begin
            if S[I] = SubStr[1] then
              begin
                X := 1;
                while (X < LenSubStr) and (S[I + X] = SubStr[X + 1]) do
                  Inc(X);
                if X = LenSubStr then
                  begin
                    Result := I;
                    exit;
                  end; //end if X
              end; //end if S[I]
              Inc(I);
         end;//end while
         Result := 0;
     end; //end else if
   end; //end function

var i,p1,p2 : integer;

begin
//initialisation fonction ChainePos
result := '';

//sortie prématurée avec séparateur en premiere position dans la chaine
if (e_posex(sep,Dans[1] = 1) and (posi <= 1) then exit;

//1ère position de lecture pour la fonction e_posex
p1 := 1;
//Boucle
for i := 1 to posi-1 do
  begin
    //recherche position prochain séparateur pour borne à gauche
    p1 := e_posex(sep,dans,p1);
    if p1 = 0 then
      exit                      //sortie prématurée pas de prochain séparateur
    else
      p1 := p1 + length(sep);   //sinon décale jusqu'à caract<>sep
                                //pour recherche suivante ou sortie
  end;

//Recherche prochain séparateur pour borne à droite...
p2 := e_posex(sep,dans,p1);
//...En cas d'absence, par défaut longueur chaine entrée+1 pour la dernier caractère
if p2 = 0 then
  p2 := length(Dans)+1;

//Fin : extraction sous-chaine de position p1, longueur p2-p1
result := copy(dans,p1,p2-p1);
end;

Conclusion :


La fonction marche si on indique un séparateur de 1 car., une chaine d'au moins 1 car. et si position est supérieur à 0 bien sûr.

A vous de juger...

A voir également