PDA

Ver la Versión Completa : Parsear texto con TString


avechuche
04-07-2013, 01:15:31
Hola gente que tal, soy nuevo por aca y estoy necesitando un poco de ayuda. Resulta que abro un archivo de texto y lo leo linea por linea con un While. Esas lineas tienen dos partes divididas por la barra "|", osea Texto1|Texto2, yo tengo que parsear ese texo para que me quede
Texto1
Texto2
El problema es el siguiente, el parseo lo hago asi
arrayColumnas := TStringList.Create;
arrayColumnas.Text := S;
arrayColumnas.StrictDelimiter := True;
arrayColumnas.Delimiter := '|';
arrayColumnas.DelimitedText := arrayColumnas.Text;
Donde "S" es cada linea del '.txt'.

El problema viene que me toma el salto de linea del final de la linea.
arrayColumnas[0] = Texto1 + ¿Un salto de linea? no se que onda
arrayColumnas[1] = Texto2 + ¿Un salto de linea? no se que onda

Use un ShowMessage con comillas para ver que cosa rara habia y me sale lo siguiente. Si el texto es asi 5|Gonzalo me muestra
"5
"
"Gonzalo
"
Las comillas tendrian que ir al final y no en la linea siguiente
Hay alguna forma de que no me tome ese salto de linea?
Gracias!

Casimiro Notevi
04-07-2013, 01:49:21
Bienvenido a clubdelphi, ¿ya leiste nuestra guía de estilo (http://www.clubdelphi.com/foros/guiaestilo.php)?, gracias por tu colaboración :)

Recuerda poner los tags al código fuente, ejemplo:

http://www.clubdelphi.com/images/UtilizarTAGs.png

Gracias :)

avechuche
04-07-2013, 02:01:47
Si disculpa, me olvide, pero no lo puedo editar ahora :(

Casimiro Notevi
04-07-2013, 02:18:41
Si disculpa, me olvide, pero no lo puedo editar ahora :(
No te preocupes, es sólo para que lo tengas en cuenta para futuros mensajes :)

ecfisa
04-07-2013, 02:56:03
Hola avechuche.

Creo que en este caso es mas simple usar la función ExtractStrings.

Como ejemplo:

...
var
i : Integer;
begin
with TStringList.Create do
try
LoadFromFile('ARCHIVO.TXT');
for i:= 0 to Count-1 do
begin
ExtractStrings(['|'], [], PChar(Strings[i]), ListBox1.Items);
ListBox1.Items.Add('---------------'); // a fin de resaltar el resultado
end;
finally
Free;
end;
end;


Pero, por si te interesa, aquí hay otras alternativas: funcion split de una cadena (http://www.clubdelphi.com/foros/showthread.php?t=75885)

Saludos :)

avechuche
04-07-2013, 04:13:37
Gracias ecfisa, funciona perfectamente. Ahora viene otra duda (Soy muy nuevo en esto)
Yo no lo quiero poner en un ListBox, quiero poner esos dos valores en cada columna de mi listbox
Hice lo siguiente

Creo el TStringList antes de entrar al "While" que recorre el ".txt"

arrayColumnas := TStringList.Create
Llamo a la funcionExtractStrings(['|'], [], PChar(S), arrayColumnas)
// Donde "S" es cada linea del ".txt" y arrayColumnas es del tipo TStringList.

Después recorro "arrayColumnas" y agrego los valores correspondientes a las columnas de mi ListView.
El problema esta que siempre me agrega la primer linea del ".txt" al ListView. Si tengo un ".txt" asi

1|Gonzalo
2|Pedro
3|Sofia

El ListView me devuelve

1|Gonzalo
1|Gonzalo
1|Gonzalo

Tengo que hacer esto arrayColumnas := TStringList.Create dentro del While asi resetea arrayColumnas ?

Osea lo hice y anda perfecto, pero está bien aplicado? porque me da que esta mal crear el TStringList cada vez que cambio la linea.

ecfisa
04-07-2013, 08:17:36
Tengo que hacer esto arrayColumnas := TStringList.Create dentro del While asi resetea arrayColumnas ?

Osea lo hice y anda perfecto, pero está bien aplicado? porque me da que esta mal crear el TStringList cada vez que cambio la linea.
Hola avechuche.

Si creas y liberas el stream cada vez, no tendría que haber problemas. Mejor tal vez sea crearlo antes del ciclo while, vaciarlo con el método Clear y liberarlo despues.

Algo como:

stream := TStringList.Create; // crear
try
while (...) do
begin
//...
stream.Clear //<== vaciar
end
finally
stream.Free // liberar
end;


También te podrías ahorrar todo el tema de leer el archivo recorriéndolo con while si usas el método LoadFromFile de TStrings. De ese modo podes acceder a cada línea del archivo mediante el índice.

Pero siendote sincero, no alcanzo a entender claramente como deseas que queden las líneas leidas desde el archivo en el stream.

Saludos. :)

nlsgarcia
04-07-2013, 09:53:31
avechuche,


...agrego los valores correspondientes a las columnas de mi ListView...El problema esta que siempre me agrega la primer linea del ".txt"...


Revisa este código:

procedure TForm1.Button1Click(Sender: TObject);
var
i,j : Integer;
StrList : TStringList;

begin

ListView1.ViewStyle := vsReport;
ListView1.Clear;

with TStringList.Create do
try
LoadFromFile('ARCHIVO.TXT');
StrList := TStringList.Create;
for i := 0 to Count-1 do
begin
ExtractStrings(['|'], [], PChar(Strings), StrList);
with ListView1.Items.Add do
begin
SubItems.Add(StrList.Strings[0]);
SubItems.Add(StrList.Strings[1]);
StrList.Clear;
end;
end;
StrList.Free;
finally
Free;
end;

end;

El código anterior [I]es una variante del sugerido en el Msg #5 adaptada a un control TListView.

Espero sea útil :)

Nelson.

avechuche
04-07-2013, 09:54:41
Aaaaaa perfecto! Eso es lo que buscaba. TStringList.Clear;

Lo que yo quiero hacer es lo siguiente, tengo un archivo txt, cada linea del txt esta compuesta por "algo de texto por aca, tiene que haber si o si|aca puede haber o no texto", digamos algo asi
1|gonzalo
2|jose
3|maria
4|
Esos serian las lineas de mi txt válidas, lo que no puede haber son lineas que no tengan nada antes de la barra "|" osea
|pepe
|feo
esas lineas son invalidas, pero eso lo compruebo a medida que voy leyendo el txt.

Ahora las lineas correctas las tengo que pasar a un Listview por eso necesito parsearlas por "|" para poner la primera parte en la primer columna del ListView y la segunda parte va a la segunda columna del ListView.
Que pasaba? Cuando parseba por "|" por alguna razon desp de cada parte del texto me ponia un salgo de linea que todavia sigo sin entender porque y si desp queria guardar los datos que habia en el ListView, me agregaba entre cada registro un salto de linea que no me gustaba, pero la funcion ExtractsString funciona de maravillas.

Con respecto a hacerlo con LoadFromFile tenes razon, lo que pasa es que yo usaba 2 TStringList uno para leer el archivo como vos me decias y el otro para almacenar las lineas parseados, desp de idas y vueltas (pensando que era eso lo que me agregaba el salto de linea a mis lineas) cambie el TStringList que leia el archivo por el "While" y adentro deje el TStringList que parseaba las lineas. Ahora tmb saque el TStringList que parsea las lineas y lo reemplaze por la funcion ExtractsString y segui dejando el "While".
Vos decis que lea el txt con LoadFromFile? Es más rapido?

PD: Si digo una vez mas TStringList bomito ^^

avechuche
04-07-2013, 09:57:24
Aaaaa mira vos asi se hace mas cortito! Muchas gracias gente por la ayuda. Ahora achico codigo como loco :)