ハスケル文字列トークナイザ関数

ハスケルにString Tokenizerが必要でしたが、Preludeや他のモジュールで定義されているものは明らかにありません。 DataTextにはsplitOnがありますが、StringをTextにラップする必要があるため、これは痛みです。

トークナイザはそれほど難しいことではありませんので、私は1つを書きました(複数の区切り文字は扱えませんが、必要なものに対してうまく機能しました)。私はこれがモジュールのどこかに既にあるべきであると感じる。

これは私のバージョンです

tokenizer :: Char -> String -> [String]
tokenizer delim str = tokHelper delim str []

tokHelper :: Char -> String -> [String] -> [String]
tokHelper d s acc 
    | null pos  = reverse (pre:acc)
    | otherwise = tokenizer d (tail pos) (pre:acc)
        where (pre, pos) = span (/=d) s

私はインターネットでより多くのソリューションを探し、このブログの投稿のような議論を見つけました。

最後のコメント(2011年6月10日のMaheeによる)は特に興味深い。これを処理するために、言葉の機能のバージョンをより一般的にするのはなぜですか?私はそのような機能を探してみましたが、何も見つかりませんでした..

これに簡単な方法があるのですか、文字列を 'トークン化'することは非常に繰り返される問題ではありませんか? :)

9
私はハスケルのプログラマーではないので、塩の穀物でこれを取る。しかし、あなたが記述しているケースは、 words よりも複雑であっても、実装するのに十分単純だと考えられます。 words レベル以外のほとんどの解析タスクはおそらく、パーサーコンビネータ(parsecなど)のようなものでやる価値があるほど複雑になるでしょう。
追加された 著者 Gian,
私は今日、Stringの代わりにTextを使うというほぼすべてのコードに対して、実際にお勧めします。パフォーマンスがはるかに優れた素晴らしいライブラリです。この声明についてさらに質問があれば、私はカフェに電子メールを送ります。
追加された 著者 Michael Snoyman,
あなたはこれについて絶対に正しいです:)ありがとうございました。私はちょっと前にlazy IOを使用していくつかの問題を抱えていました(getContentsとgetLineで動作させるために何時間も試してみました。しかしTextに相当する関数を使って、私の問題は即座に解決されました。テキストを使用するとパフォーマンスが悪化するかどうかは分かりませんが、最終的にはアプリに大きな違いはありません。テキストの仕組みをより詳しく調べる必要があります:)
追加された 著者 Adi,

2 答え

分割ライブラリが必要です。 cabal install split でインストールすると、多くの分割/トークナイザスタイル関数にアクセスできます。

ライブラリのいくつかの例:

 > import Data.List.Split
 > splitOn "x" "axbxc"
 ["a","b","c"]
 > splitOn "x" "axbxcx"
 ["a","b","c",""]
 > endBy ";" "foo;bar;baz;"
 ["foo","bar","baz"]
 > splitWhen (<0) [1,3,-4,5,7,-9,0,2]
 [[1,3],[5,7],[0,2]]
 > splitOneOf ";.," "foo,bar;baz.glurk"
 ["foo","bar","baz","glurk"]
 > splitEvery 3 ['a'..'z']
 ["abc","def","ghi","jkl","mno","pqr","stu","vwx","yz"]

同じライブラリの wordsBy 関数は、 words の汎用バージョンです。

wordsBy (=='x') "dogxxxcatxbirdxx" == ["dog","cat","bird"]
15
追加された
ありがとう、これはちょうど私が必要なものでした
追加された 著者 Adi,

If you're parsing a Haskell-like language you can use the lex function from the Prelude: http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:lex

4
追加された