2014-01-23 2 views
4

Моя цель - найти количество раз, когда подстрока существует внутри строки. Подстрока, которую я ищу, будет иметь тип «[n]», где n может быть любой переменной.Haskell extract substring внутри строки

Моей попытки предполагается разбить строку вверх с помощью функции слова, затем создать новый список строк, если «голова» строка была «[» и «последний» из тех же строк была «]»

проблема я столкнулся в том, что я вошел в строку, когда раскол, используя функциональные слова, создали строку, которая выглядела, как это «[2],» Теперь, я все еще хочу, чтобы это рассчитывать как возникновение тип «[n]»

Примером может служить эта строка,

ASDF [1] JKL [2] ASDF [1] JKL

вернуться 3.

Вот код, у меня есть:

-- String that will be tested on references function 
txt :: String 
txt = "[1] and [2] both feature characters who will do whatever it takes to " ++ 
    "get to their goal, and in the end the thing they want the most ends " ++ 
    "up destroying them. In case of [2], this is a whale..." 

-- Function that will take a list of Strings and return a list that contains 
-- any String of the type [n], where n is an variable 
ref :: [String] -> [String] 
ref [] = [] 
ref xs = [x | x <- xs, head x == '[', last x == ']'] 

-- Function takes a text with references in the format [n] and returns 
-- the total number of references. 
-- Example : ghci> references txt -- -> 3 
references :: String -> Integer 
references txt = len (ref (words txt)) 

Если кто-нибудь может просветить меня о том, как искать подстроку в строке или как разбирать строку с подстрокой, что было бы весьма полезно.

ответ

2

регулярное выражение огромна избыточна для такой простой задачи.

references = length . consume 

consume []  = [] 
consume ('[':xs) = let (v,rest) = consume' xs in v:consume rest 
consume (_ :xs) = consume xs 

consume' []  = ([], []) 
consume' (']':xs) = ([], xs) 
consume' (x :xs) = let (v,rest) = consume' xs in (x:v, rest) 

consume ждет в [, затем вызывает consume', который не собирает все, пока ].

+0

Я предпочитаю это по другому ответу, потому что A) это сжатое решение в Haskell, а не в Regex; и B) это, вероятно, упрощает понимание и модификацию для использования ПП. – jcarpenter2

4

Я просто хотел бы использовать регулярное выражение, и написать это:

import Text.Regex.Posix 

txt :: String 
txt = "[1] and [2] both feature characters who will do whatever it takes to " ++ 
    "get to their goal, and in the end the thing they want the most ends " ++ 
    "up destroying them. In case of [2], this is a whale..." 


-- references counts the number of references in the input string 
references :: String -> Int 
references str = str =~ "\\[[0-9]*\\]" 

main = putStrLn $ show $ references txt -- outputs 3 
+0

Спасибо, jcarpenter! Не могли бы вы объяснить, что делает оператор = ~? Является ли это частью импортированной библиотеки? Я был moreso надеясь выяснить, как анализировать, когда [n] происходит, потому что я хотел бы в конечном итоге заменить каждый [n] на String, который находится в списке, индексированном любым n. –

+0

Я не знаю, как = ~ работает внутри. Он соответствует регулярному выражению против строки и может возвращать различные типы. Google или другие люди могут это сделать лучше, чем я могу. – jcarpenter2

Смежные вопросы