Вы можете использовать простую рекурсию трюк, например
findTag [] = -- end of list code.
findTag ('@':xs)
| take 5 xs == "title" = -- your code for @title
| otherwise = findTag xs
findTag (_:xs) = findTag xs
так в основном вы просто шаблон матч, если следующий символ (глава списка) является «@», а затем проверить, если следующие 5 символов образуют "заглавие". если это так, вы можете продолжить свой синтаксический код. если следующий символ isnt '@', вы просто продолжаете рекурсию. Как только список пуст, вы достигнете первого совпадения.
У кого-то может быть лучшее решение.
Надеюсь, это ответит на ваш вопрос.
редактировать:
Для гибкости немного больше, если вы хотите найти конкретный тег вы могли бы сделать это:
findTag [] _ = -- end of list code.
findTag ('@':xs) tagName
| take (length tagName) xs == tagName = -- your code for @title
| otherwise = findTag xs
findTag (_:xs) _ = findTag xs
Таким образом, если вы
findTag text "title"
Вы» В частности, вы ищете название, и вы всегда можете изменить тэг на все, что захотите.
Другой редактировать:
findTag [] _ = -- end of list code.
findTag ('@':xs) tagName
| take tLength xs == tagName = getTagContents tLength xs
| otherwise = findTag xs
where tLength = length tagName
findTag (_:xs) _ = findTag xs
getTagContents :: Int -> String -> String
getTagContents len = takeWhile (/=')') . drop (len + 1)
быть честным, это становится немного неаккуратно, но вот что происходит:
Вы первый уронить длину тэгу, а затем еще один для открывающей скобки, и то вы закончите с помощью takeWhile, чтобы взять символы до закрытия скобки.
Написать пар. Вы можете сделать другие хаки, которые проще в краткосрочной перспективе, но вы пожалеете об этом позже. –
А по теме парсеров принадлежит Парсек. –
@CatPlusPlus Это спорно. С точки зрения производительности Attoparsec может часто превзойти ее. –