Вы можете использовать простой прием рекурсии, например
findTag [] = -- end of list code.
findTag ('@':xs)
| take 5 xs == "title" = -- your code for @title
| otherwise = findTag xs
findTag (_:xs) = findTag xs
так что в основном вы просто сопоставляете шаблон, если следующий символ (голова списка) равен «@», а затем вы проверяете, образуют ли следующие 5 символов «заголовок». если это так, вы можете продолжить свой код синтаксического анализа. если следующий символ не '@', вы просто продолжаете рекурсию. Когда список пуст, вы достигаете первого совпадения с образцом.
У кого-то может быть лучшее решение.
Надеюсь, это ответит на ваш вопрос.
редактировать:
Для большей гибкости, если вы хотите найти конкретный тег, вы можете сделать это:
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)
если честно, это становится немного запутанным, но вот что происходит:
Сначала вы опускаете длину tagName, затем еще одну для открывающей скобки, а затем завершаете с помощью takeWhile, чтобы доставить символы до закрывающей скобки.
person
Attic
schedule
16.02.2013