2

Clojure で単純な正規表現を動作させて、いくつかの SQL 予約語 (select、from、where など) の文字列をテストしようとしましたが、動作させることができません:

(defn areserved? [c]
  (re-find #"select|from|where|order by|group by" c))

(文字列をスペースで分割してから、すべての単語を調べます)

助けていただければ幸いです。

ありがとう!


編集: 私の最初の目標 (いくつかの例と基本的な Clojure 資料を読んだ後) は、文字列を解析し、その各部分 (つまり、単語) に対して、ステートメント (予約語、文字列など) に含まれる「ジョブ」を返すことです。 )。

私がこれまでに持っているもの:

(use '[clojure.string :only (join split)])

(defn isdigit? [c]
  (re-find #"[0-9]" c))

(defn isletter? [c]
  (re-find #"[a-zA-Z]" c))

(defn issymbol? [c]
  (re-find #"[\(\)\[\]!\.+-><=\?*]" c))

(defn isstring? [c]
  (re-find #"[\"']" c))

(defn areserved? [c]
  (if (re-find #"select|from|where|order by|group by" c)
      true
      false))

(defn what-is [token]
  (let [c (subs token 0 1)]
    (cond
      (isletter? c)  :word
      (areserved? c) :reserved
      (isdigit? c)   :number
      (issymbol? c) :symbol
      (isstring? c) :string)))

(defn checkr [token]
  {:token token
   :type (what-is token)})

(defn goparse [sql-str]
  (map checkr (.split sql-str " ")))

みんな助けてくれてありがとう!このような比較的新しい言語に対する多くのサポートを見るのは素晴らしいことです (少なくとも私にとっては :))

4

1 に答える 1

4

あなたが正確に何を望んでいるかは完全にはわかりませんが、最初の正規表現の一致をブール値に強制するためのいくつかのバリエーションがあります。

(defn areserved? [c]
  (string?
    (re-find #"select|from|where|order by|group by"c)))

(defn areserved? [c]
  (if (re-find #"select|from|where|order by|group by"c)
      true
      false))

質問の編集に応じて更新:

より多くのコードを投稿していただきありがとうございます。残念ながら、既存のコードに単純でナイーブな方法でパッチを適用することで対処できる問題がいくつかありますが、この 1 回の反復アプローチで次の問題に遭遇する前に、これまでのところしか解決できません。

@alexは正しいです。文字列を空白ですでに分割している場合、areserved?メソッドは一致しません。そうは言っても、簡単な修正は、 andを別々のキーワードとしてorder by扱うことです (これらは常に一緒に表示されますが、それらは同じです)。orderby

次の問題は、areserved?関数は文字列内のキーワードに一致しますが、関数内の文字に対してディスパッチしていることwhat-isです。ほとんどの場合、 for で一致するcondためisletter?、すべてが「単語」としてマークされます。

全体として、 の単一のアプリケーションであまりにも多くの作業をしようとしているようですmap

Clojure で遊ぶためにこれを行っているだけなのかどうかはわかりません (これは素晴らしいことです - 続けてください!)。きっと何かを学ぶでしょう。しかし、さらに進んで SQL をよりうまく解析したい場合は、LexingParsing 、およびAbstract Syntax Trees (AST)の構築について少し読むと役立つかもしれません。

Brian Carper は、Clojure の Java パーサー ジェネレーター「ANTLR」の使用について書いています。これは数年前のものですが、一見の価値があるかもしれません。

また、SQL の字句解析と解析に関する F# プログラミングの本から、この章からいくつかの移転可能なアイデアを得ることができるかもしれません。

于 2013-01-15T18:32:16.657 に答える