递归 – 在功能上按空格分割字符串,按引号分组!

栏目: 编程语言 · Clojure · 发布时间: 7年前

内容简介:翻译自:https://stackoverflow.com/questions/4334897/functionally-split-a-string-by-whitespace-group-by-quotes

在Clojure [1]中编写惯用的函数代码,如何编写一个用空格分割字符串但保持引用短语完整的函数?一个快速的解决方案当然是使用正则表达式,但没有它们就可以实现.快速浏览一下似乎很难!我在命令式语言中写了类似的但我想看看功能性的递归方法是如何工作的.

快速查看我们的功能应该做什么:

"Hello there!"  -> ["Hello", "there!"]
"'A quoted phrase'" -> ["A quoted phrase"]
"'a' 'b' c d" -> ["a", "b", "c", "d"]
"'a b' 'c d'" -> ["a b", "c d"]
"Mid'dle 'quotes do not concern me'" -> ["Mid'dle", "quotes do not concern me"]

我不介意引号之间的间距是否变化(因此可以先使用空格分割简单).

"'lots    of   spacing' there" -> ["lots of spacing", "there"] ;is ok to me

[1]这个问题可以在一般水平上回答,但我想Clojure中的功能方法可以轻松地转换为Haskell,ML等.

这是一个返回lazy seq of words / quoted strings的版本:

(defn splitter [s]
  (lazy-seq
   (when-let [c (first s)]
     (cond
      (Character/isSpace c)
      (splitter (rest s))
      (= \' c)
      (let [[w* r*] (split-with #(not= \' %) (rest s))]
        (if (= \' (first r*))
          (cons (apply str w*) (splitter (rest r*)))
          (cons (apply str w*) nil)))
      :else
      (let [[w r] (split-with #(not (Character/isSpace %)) s)]
        (cons (apply str w) (splitter r)))))))

试运行:

user> (doseq [x ["Hello there!"
                 "'A quoted phrase'"
                 "'a' 'b' c d"
                 "'a b' 'c d'"
                 "Mid'dle 'quotes do not concern me'"
                 "'lots    of   spacing' there"]]
        (prn (splitter x)))
("Hello" "there!")
("A quoted phrase")
("a" "b" "c" "d")
("a b" "c d")
("Mid'dle" "quotes do not concern me")
("lots    of   spacing" "there")
nil

如果输入中的单引号与正确匹配,则最终打开单引号中的所有内容都将构成一个“单词”:

user> (splitter "'asdf")
("asdf")

更新:另一个版本回答edbond的评论,更好地处理单词中的引号字符:

(defn splitter [s]
  ((fn step [xys]
     (lazy-seq
      (when-let [c (ffirst xys)]
        (cond
         (Character/isSpace c)
         (step (rest xys))
         (= \' c)
         (let [[w* r*]
               (split-with (fn [[x y]]
                             (or (not= \' x)
                                 (not (or (nil? y)
                                          (Character/isSpace y)))))
                           (rest xys))]
           (if (= \' (ffirst r*))
             (cons (apply str (map first w*)) (step (rest r*)))
             (cons (apply str (map first w*)) nil)))
         :else
         (let [[w r] (split-with (fn [[x y]] (not (Character/isSpace x))) xys)]
           (cons (apply str (map first w)) (step r)))))))
   (partition 2 1 (lazy-cat s [nil]))))

试运行:

user> (doseq [x ["Hello there!"
                 "'A quoted phrase'"
                 "'a' 'b' c d"
                 "'a b' 'c d'"
                 "Mid'dle 'quotes do not concern me'"
                 "'lots    of   spacing' there"
                 "Mid'dle 'quotes do no't concern me'"
                 "'asdf"]]
        (prn (splitter x)))
("Hello" "there!")
("A quoted phrase")
("a" "b" "c" "d")
("a b" "c d")
("Mid'dle" "quotes do not concern me")
("lots    of   spacing" "there")
("Mid'dle" "quotes do no't concern me")
("asdf")
nil

翻译自:https://stackoverflow.com/questions/4334897/functionally-split-a-string-by-whitespace-group-by-quotes


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

码出高效:Java开发手册

码出高效:Java开发手册

杨冠宝、高海慧 / 电子工业出版社 / 2018-10 / 99.00元

《码出高效:Java 开发手册》源于影响了全球250万名开发工程师的《阿里巴巴Java开发手册》,作者静心沉淀,对Java规约的来龙去脉进行了全面而彻底的内容梳理。《码出高效:Java 开发手册》以实战为中心,以新颖的角度全面阐述面向对象理论,逐步深入地探索怎样成为一位优秀开发工程师。比如:如何驾轻就熟地使用各类集合框架;如何得心应手地处理高并发多线程问题;如何顺其自然地写出可读性强、可维护性好的......一起来看看 《码出高效:Java开发手册》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

在线进制转换器
在线进制转换器

各进制数互转换器