2010-07-30 6 views
6

Jaki jest (lub jest) idiomatyczny sposób na pozbycie się znaków nowej linii ze stringów w Haskell? Czy muszę tworzyć własne, znajdując końcowe znaki/spacje, a następnie je usuwając?Zdejmowanie nowych linii w Haskell

EDIT: Patrzę na to, co robi rstrip Pythona, ale nie muszą opcjonalne "znaki" Argument:

string.rstrip (s [, chars])

zwróci kopia ciągu znaków z usuniętymi znakami końcowymi. Jeśli znaki są pominięte lub brak, znaki białej spacji są usuwane. Jeśli podano i nie ma wartości Brak, znaki muszą być ciągiem znaków; znaków w łańcuchu będzie usunięty z końca ciągu ta metoda jest wywoływana.

+2

Choć obie twoje pytanie i różne odpowiedzi udzielone kontrakt z realizacją 'rstrip' funkcji Pythona w Haskell, używając nie jest bardzo idiomatyczne w Haskell w większości przypadków. Zwykle używałbyś 'linii' i' słów', chyba że jest jakiś inny wyjątek. – Yitz

Odpowiedz

9

Oto jedna prosta implementacja (zaadaptowane z Wikipedia):

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

Jest też rstrip już zdefiniowane w Data.String.Utils.

(Nawiasem mówiąc, Hayoo! jest doskonałym źródłem informacji dla tego rodzaju pytania: poszukiwanie rstrip zabierze Cię bezpośrednio do Data.String.Utils.)

+0

Nigdy nie zaglądałem do Data.String.Utils przed. Przydatny. I rstrip wygląda dokładnie tak, jak chciał. –

3

W zależności od tego, co masz na myśli:

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

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

Ale to nie mamy do czynienia ze spacjami ładnie. Więc może nie tego, czego szukasz.

+2

Żadne z nich nie "rozciąga" ciągu znaków (w zwykłym znaczeniu "usuń znaki początkowe lub końcowe"). –

2

Kiedyś to drugi dzień:

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

To jest ta sama zasada, co odpowiedź Travisa. – kennytm

+0

Tak, domyślam się, że pisaliśmy w tym samym czasie.Ale mój robi to, o co prosił plakat! Głosujcie na mnie! :) –

+0

Myślę, że trimnl = reverse. dropwhile ('elem'" \ n \ r \ t "). odwrotność byłaby bliższa rtrimowi w pytonie –

3

Jeśli jest to dla typowej aplikacji pliku czytania, to powinieneś zacząć lines. Może to pozwolić na uniknięcie Data.String.Utils.rstrip całkowicie:

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

Jak widać, lines bierze tekst całego pliku i odpowiednio zmienia każdą linię na sznurku bez spływu linią. Oznacza to, że można napisać program tak:

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