2010-07-30 13 views
6

¿Cuál es la (o hay) una forma idiomática de quitar líneas nuevas de las cadenas en Haskell? ¿O tengo que crear el mío encontrando las nuevas líneas/espacios al final y luego eliminándolos?Stripping newlines en Haskell

EDIT: Estoy buscando lo que hace rstrip de Python, pero que no necesitan los "caracteres" opcionales argumento:

string.rstrip (s [,] chars)

devolver una copia de la cadena con los caracteres finales eliminados. Si se omiten los caracteres o Ninguno, se eliminan los espacios en blanco . Si se da y no es Ninguno, los caracteres deben ser una cadena; los caracteres en la cadena serán eliminados del final de la cadena en la que se invoca este método.

+2

Mientras tanto su pregunta y las diversas respuestas dadas acuerdo con la implementación de la función 'rstrip' de Python en Haskell, su uso no es muy idiomático en Haskell en la mayoría de los casos. Usualmente usarías 'líneas' y' palabras', a menos que exista alguna razón especial de lo contrario. – Yitz

Respuesta

9

Aquí hay una implementación simple (adaptado de Wikipedia):

import Data.Char (isSpace) 
rstrip = reverse . dropWhile isSpace . reverse 

También hay un rstrip ya definido en Data.String.Utils.

(Por cierto, Hayoo! es un gran recurso para este tipo de preguntas: una búsqueda de rstrip le lleva directamente a Data.String.Utils.)

+0

Nunca miré en Data.String.Utils antes. Útil. Y rstrip parece exactamente lo que se quiere. –

3

Dependiendo de lo que quiere decir:

 
Prelude> filter (/= '\n') "foo\n\nbar\n" 
"foobar" 

Prelude> words "foo\n\nbar\n" 
["foo","bar"] 

Pero éstos no tratan con espacios muy bien. Entonces tal vez no es lo que estás buscando.

+2

Ninguno de estos realmente "tiras" la cadena, sin embargo (en el sentido habitual de "eliminar los caracteres iniciales o finales"). –

2

he usado esto el otro día:

Prelude> let trimnl = reverse . dropWhile (=='\n') . reverse 
Prelude> trimnl "" 
"" 
Prelude> trimnl "\n" 
"" 
Prelude> trimnl "a\n" 
"a" 
Prelude> trimnl "a\n\n" 
"a" 
Prelude> trimnl "a\nb\n" 
"a\nb" 
+0

Ese es el mismo principio que la respuesta de Travis. – kennytm

+0

Sí, creo que escribimos al mismo tiempo.¡Pero el mío hace lo que el cartel pidió! ¡Vota por mí! :) –

+0

Creo trimnl = inversa. dropwhile ('elem'" \ n \ r \ t "). revertir estaría más cerca de la rtrim en python –

3

Si se trata de una aplicación típica de archivos de lectura, entonces probablemente debería comenzar con lines. Esto puede permitir que usted pueda evitar por completo Data.String.Utils.rstrip:

> lines "one time\na moose\nbit my sister\n" 
["one time", "a moose", "bit my sister"] 

Como se puede ver, lines toma el texto del archivo completo y correctamente se convierte cada línea en una cadena sin salto de línea final. Esto significa que puede escribir un programa de este modo:

main = mapM_ (putStrLn . process) . lines =<< readFile "foo.txt" 
    where process :: String -> String 
     process = -- your code here --