Как разбить строку в пробелах, которые не ускользнули? - PullRequest
0 голосов
/ 22 июня 2019

Я хотел бы разбить мою строку на неэкранированные пробелы, как это:

let s = "number\\ 1 number\\ 2 number\\ 3"


["number\\ 1", "number\\ 2", "number\\ 3"]

or even better

["number 1", "number 2", "number 3"]

Как мне это сделать?

Попытка 1:

let s = "number\\ 1 number\\ 2 number\\ 3"

splitWhitespace :: String -> [String]
splitWhitespcae s = splitOn " " s
-- returns ["number\\","1","number\\","2","number\\","3"]

concatBackslash :: [String] -> [String]
concatBackslash [] = []
concatBackslash (x : xx : xs) = case init x of
    "\\" -> (x ++ xx) : concatBackslash xs
    _ -> x : xx : concatBackslash x

Но по какой-то причине это возвращает тот же список.

Попытка 2:

splitOnWhitespace :: String -> [String]
splitOnWhitespace s = splitOn " " s

concatBackslash :: [String] -> [String]
concatBackslash [] = []
concatBackslash [x, xs] = case last x of
    '\\' -> [(init x) ++ xs]
    _ -> [x, xs]
concatBackslash (x : xx : xs) = case last x of
    '\\' -> concatBackslash (((init x) ++ xx) : xs)
    _ -> x: concatBackslash (xx : xs)

Это было сделано с помощью @leftaroundabout, однако я закончил без пробелов.

> let s = "number\\ 1 number\\ 2 number\\ 3"
> concatBackslash $ splitOnWhitespace s
["number1","number2","number3"]

1 Ответ

2 голосов
/ 22 июня 2019

Две проблемы:

  • init дает вам все , за исключением последнего символа в строке.Но когда вы пытаетесь сопоставить с "\\", это будет истинно последний символ.Таким образом, вы должны использовать last в операторе case.
  • Если вам нужно init, то это когда ++ объединяет этот элемент со следующим.Именно в этом случае вы не хотите сохранять трейлинг \, но все перед ним.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...