Вырезать строку в список в Haskell? - PullRequest
3 голосов
/ 03 мая 2011

можно ли отрезать строку, например

"one , Two"

к списку

["one", "two"]

или просто

"one", "two"

спасибо

Ответы [ 4 ]

7 голосов
/ 03 мая 2011

Существует целый модуль функций для различных стратегий разделения списка (например, строки, представляющей собой просто список символов): Data.List.Split

Использование этогоВы могли бы сделать

import Data.List.Split

> splitOn " , " "one , Two"
["one","Two"]
2 голосов
/ 04 мая 2011

Если вы не хотите устанавливать разделенный пакет (, см. Ответ Фрериха Раабе ), вот реализация функции splitOn, которая облегчает зависимости:

import Data.List

splitOn :: Eq a => [a] -> [a] -> [[a]]
splitOn []    _  = error "splitOn: empty delimiter"
splitOn delim xs = loop xs
    where loop [] = [[]]
          loop xs | delim `isPrefixOf` xs = [] : splitOn delim (drop len xs)
          loop (x:xs) = let (y:ys) = splitOn delim xs
                         in (x:y) : ys
          len = length delim
2 голосов
/ 03 мая 2011

Здесь достаточно регулярных операций со старым списком,

import Data.Char

> [ w | w <- words "one , Two", all isAlpha w ]
["one","Two"]

ака

> filter (all isAlpha) . words $ "one , Two"
["one","Two"]

Список взлома, разбор и оформление

Существует шкала силы и веса при обработке текста. В простейших решениях на основе списков, таких как приведенные выше, предлагают очень мало синтаксического шума для быстрых результатов (в том же духе, что и быстрая и нездоровая обработка текста в сценариях оболочки).

Манипулирование списками может стать довольно сложным, и вы можете рассмотреть, например, обобщенная библиотека split , для разбиения списков на произвольный текст,

> splitOn " , " "one , Two"
["one","Two"]

Для более сложных задач или для кода, который вряд ли будет выброшен, более надежные методы имеют смысл. В частности, вы можете избежать хрупкого сопоставления с образцом, описав проблему как грамматику с помощью комбинаторов синтаксического анализа, таких как parsec или uu-parsinglib . Строковая обработка, описанная с помощью синтаксических анализаторов, имеет тенденцию со временем приводить к более устойчивому коду, поскольку при изменении требований относительно легко модифицировать синтаксические анализаторы, написанные в стиле комбинатора.

Примечание к регулярным выражениям: сопоставление списков и регулярные выражения примерно эквивалентны в простоте использования и (не) безопасности, поэтому для целей этого обсуждения вы можете заменить "регулярное выражение" на "разбиение списка". Синтаксический анализ - почти всегда правильный подход, если код предназначен для длительного использования.

0 голосов
/ 03 мая 2011

Не проверено, с использованием Parsec.Возможно, есть и разделитель регулярных выражений.

firstElement :: Parser String
firstElement = many $ noneOf ' '

otherElement :: Parser String
otherElement = do many $ char ' '
                  char ','
                  many $ char ' '
                  firstElement

elements :: Parser [String]
elements = liftM2 (:) firstElement (many otherElement)

parseElements :: String -> [String]
parseElements = parse elements "(unknown)"

Было бы неплохо как-то очистить otherElement, подобно тому, как мне удалось свернуть elements с помощью liftM2.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...