1

Haskell Parsec ライブラリを使用して、ウィキペディアの XML ダンプを解析して、各ページの特定のリンクを見つけようとしています。リンクは二重括弧で示されます: texttext[[link]]texttext. シナリオを可能な限り単純化するために、二重中括弧 (ネスト可能) で囲まれていない最初のリンクを探しているとします{{ {{ [[Wrong Link]] }} [[Wrong Link]] }} [[Right Link]]。ネストされていない二重中括弧で囲まれているリンクを破棄するパーサーを作成しました。

import Text.Parsec

getLink :: String -> Either ParseError String
getLink = parse linkParser "Links"

linkParser = do
    beforeLink
    link <- many $ noneOf "]"
    string "]]"
    return link

beforeLink = manyTill (many notLink) (try $ string "[[")

notLink = try doubleCurlyBrac <|> (many1 normalText)

normalText = noneOf "[{"
           <|> notFollowedByItself '['
           <|> notFollowedByItself '{'

notFollowedByItself c = try ( do x <- char c
                                 notFollowedBy $ char c
                                 return x)

doubleCurlyBrac = between (string "{{") (string "}}") (many $ noneOf "}")

getLinkTest = fmap getLink testList
    where testList = ["   [[rightLink]]   "                            --Correct link is found
                     , "  {{    [[Wrong_Link]]    }}  [[rightLink]]"   --Correct link is found
                     , "  {{  {{ }} [[Wrong_Link]] }} [[rightLink]]" ] --Wrong link is found 

doubleCurlyBracネストされた中括弧内のリンクも破棄するようにパーサーを再帰的にしようとしましたが、成功しませんでした。

doubleCurlyBrac = between (string "{{") (string "}}") betweenBraces
        where betweenBraces = doubleCurlyBrac <|> (many $ try $ noneOf "}")

このパーサーは}}、ネストされた例では、最後のものではなく、最初の の後に入力の消費を停止します。(この場合) ネストされた二重中括弧内のリンクを正しく無視する再帰パーサーを作成するエレガントな方法はありますか? また、使わなくてもできtryますか?はtry入力を消費しないため、パーサーが予期しない不適切な形式の入力でハングすることがよくあります。

4

2 に答える 2