【问题标题】:Tokenizing a string in Clojure在 Clojure 中标记字符串
【发布时间】:2014-07-26 10:43:22
【问题描述】:

我正在尝试使用 clojure 标记字符串。基本标记化规则要求将字符串拆分为单独的符号,如下所示:

  1. “hello world”形式的字符串文字是单个标记
  2. 不属于字符串文字的每个单词都是一个标记
  3. 每个非单词字符都是一个单独的标记

例如,给定字符串: length=Keyboard.readInt("HOW MANY NUMBERS? ");

我希望它被标记为:

["length" "=" "Keyboard" "." "readInt" "(" "\"HOW MANY NUMBERS? \"" ")" ";"]

我已经能够根据上面的规则 2 和 3 编写一个函数来拆分字符串。我无法满足第一条规则。 意思是,目前上面的字符串拆分如下:

["let" "length" "=" "Keyboard" "." "readInt" "(" "\"HOW" "MANY" "NUMBERS?" "\"" ")" ";"]

这是我的功能:

(defn TokenizeJackLine [LineOfJackFile]
  (filter not-empty 
    (->
 (string/trim LineOfJackFile)
 ; get rid of all comments
 (string/replace #"(//.*)|(\s*/?\*.*?($|\*/))|([^/\*]*\*/)" "") 
 ; split into tokens using 0-width look-ahead
 (string/split #"\s+|(?<=[\{\}\(\)\[\]\.,;+\-\*/&\|<>=~])|(?=[\{\}\(\)\[\]\.,;+\-\*/&\|<>=~])")
 )))

如何编写一个函数,将字符串拆分为符合上述所有三个规则的标记?或者,我应该采取什么其他方法来实现所需的标记化?谢谢。

【问题讨论】:

  • 而不是正则表达式(错误的工作工具!)我建议使用 instaparse。 github.com/Engelberg/instaparse
  • @progo 谢谢,但如果能找到一个简单的内置方法来做到这一点,那就太好了。
  • 只有一个好的解析器才能让解析变得简单。
  • @noisesmith 我现在不想解析字符串,而是将其拆分为标记。
  • lexing 是一个实现细节,一些解析器(如 yacc)有单独的词法分析阶段,有些(如 clojure 的 instaparse)不分离这些阶段

标签: regex clojure tokenize


【解决方案1】:

删除初始 \s+|从你的分裂使它按照你想要的方式工作。这导致字符串在空白字符上拆分。

(defn TokenizeJackLine [LineOfJackFile]
  (filter not-empty 
    (->
 (clojure.string/trim LineOfJackFile)
 ; get rid of all comments
 (clojure.string/replace #"(//.*)|(\s*/?\*.*?($|\*/))|([^/\*]*\*/)" "") 
 ; split into tokens using 0-width look-ahead
 (clojure.string/split #"(?<=[\{\}\(\)\[\]\.,;+\-\*/&\|<>=~])|(?=[\{\}\(\)\[\]\.,;+\-\*/&\|<>=~])")
 )))

(def input "length=Keyboard.readInt(\"HOW MANY NUMBERS? \");")
(TokenizeJackLine input)

产生这个输出:

("length" "=" "Keyboard" "." "readInt" "(" "\"HOW MANY NUMBERS? \"" ")" ";")

【讨论】:

  • 是的,但它会在其他字符串上失败。例如:对于字符串:"function void main() {" 结果不正确:["function void main" "(" ")" " " "{"]
  • 啊...好吧,你是对的。您需要一种方法来提取带引号的字符串,这有点超出我的正则表达式技能。
猜你喜欢
  • 2010-09-20
  • 2011-11-28
  • 2011-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多