【问题标题】:Clojure re-find reg-ex ORClojure 重新查找 reg-ex 或
【发布时间】:2013-01-15 18:05:31
【问题描述】:

我一直在尝试让一个简单的 reg-ex 在 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 " ")))

感谢大家的帮助!很高兴看到对这种相对较新的语言有如此多的支持(至少对我来说:))

【问题讨论】:

  • 如果你用空格分割,那么在你的模式中包含“order by”和“group by”是没有意义的。
  • 您能否更详细地说明它是如何不起作用的?如果您的函数匹配得太急切(例如(areserved? "whereto"),您可能希望使用re-matches。或者如果它过于区分大小写(例如(areserved? "WHERE")),您可能需要将(?i:...) 包裹在您的正则表达式组周围。在任何阅读 Clojure regexjava.util.regex.Pattern 的文档的案例会有所帮助。

标签: clojure


【解决方案1】:

我不完全确定您到底想要什么,但这里有一些变体可以将您的第一个正则表达式匹配强制为布尔值:

(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))

更新问题编辑:

感谢您发布更多代码。不幸的是,这里有很多我们可以解决的问题 尝试通过以简单和幼稚的方式修补现有代码来解决问题,但它会 在您使用这种单次迭代方法遇到下一个问题之前,您只能做到这一点。

@alex 是正确的,你的 areserved? 方法将无法匹配 order by 如果你已经 用空格分割你的字符串。也就是说,一个简单的解决方法是将 orderby 视为单独的关键字(尽管它们总是一起出现)。

下一个问题是areserved? 函数将匹配字符串中的关键字,但您将它分派给what-is 函数中的字符。您几乎总是在cond 中找到与isletter? 匹配的内容,因此您会将所有内容都标记为“单词”。

总而言之,您似乎试图在 map 的单个应用程序中做太多工作。

我不确定您这样做是否只是为了玩 Clojure 的乐趣(这令人钦佩 - 继续前进!),在这种情况下,如果您继续使用这种简单的解析方法可能并不重要。 ..你肯定会学到一些东西;但如果您想更进一步并更成功地解析 SQL,那么我建议您在 LexingParsing 上阅读一些内容可能会有所帮助strong> 并构建 Abstract Syntax Trees (AST)。

Brian Carper 曾写过关于使用 Java parser generator "ANTLR" from Clojure 的文章 - 它已经有几年历史了,但可能值得一看。

您还可以从this chapter from the F# programming book on lexing and parsing SQL 获得一些可转移的想法。

【讨论】:

  • 嗨,很抱歉没有澄清,我正在尝试编写一个简单的程序来解析/验证来自用户的字符串。由于无法通过正则表达式完全测试 SQL,我试图只使用一个简单的查询行(例如“从中选择这个”)并检查其中每个单词符合什么分类(保留字、数字、字符串、字ETC)。这是我第一次尝试 Clojure,我遇到了正则表达式匹配的问题。谢谢!
  • @RX 这应该可以解决(含糊地)说明的问题。如果您仍然遇到问题,请尝试发布一个更完整的示例,其中包含测试数据,以说明您如何调用函数以及预期与观察到的结果。
  • @RX 我猜了你想要什么,但显然错过了。您能否添加一些具有预期输出的示例输入?我相信 Clojure 社区会挺身而出并提供帮助,只要我们确切知道您想要什么 :-)
  • 更新了我的帖子,一开始就应该这样做。谢谢大家!
猜你喜欢
  • 1970-01-01
  • 2023-03-03
  • 2011-11-16
  • 2017-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-03
  • 2016-04-06
相关资源
最近更新 更多