切换大量Clojure代码的区分大小写

时间:2017-05-02 13:05:19

标签: clojure

有一大块代码(大部分不是我的代码)通过用户输入执行以下操作(或多或少,带有一些参数/选项的空格分隔的命令列表):

  1. 删除所有不支持的字符
  2. 将空间拆分为矢量
  3. 在向量中递归地应用向量中的第一个项目(函数使用它需要的任何参数,并返回不带自身的向量及其参数到循环中)。
  4. 就输入而言,函数本身混合了(case),(cond),(condp),(=)和(compare)混合的一些讨厌(关键字)比较。

    每个人都很好,事实上这一切都是严格区分大小写的,直到最近。现在一些(以前未知的)古代集成位作为用户出现,并且有一些我无法控制的套管问题。

    问题:是否有一种可行的方法(在有更多时间重做之前的快捷方式)根据某些变量使某些范围的字符串比较不敏感?

    我考虑了3个选项:

    1. 修复代码(无论如何都会完成,但目前还不行)。
    2. 提取一些低级别比较功能(希望只有一个)并将其重新绑定到本地范围(听起来不错,但抓住案例可能很困难且容易出错)。
    3. 标准化输入(如果没有一些黑客可能无法实现,因为有些数据,在比较之外,需要区分大小写)。
    4. 经过一些研究,答案可能是否定的(并且应该开始计划进行重大改变),但我认为要求不会受到伤害,也许有人在考虑之前。

      编辑:示例有问题的输入:

      "Command1 ARG1 aRG2 Command3 command9 Arg4 Arg9 aRg5 COMMAND4 arg8"
      

      打破它: 破坏案例的“命令”我需要能够根据需要不区分大小写。参数在另一个级别上不区分大小写 - 因此它们不涉及这段代码,但是应该保留它们在这段代码中的情况以便进一步发送。 NB!在处理开始时,不可能告诉输入命令和参数是什么。

1 个答案:

答案 0 :(得分:0)

对于它的价值,这里是一个简单的case形式的不区分大小写的包装器:

(ns lexer.core)

(defn- standardize [thing]
  (assert (string? thing) (str thing " should be a string"))
  (clojure.string/lower-case thing))

(defmacro case-insensitive-case [expr & pairs+default?]
  (let [pairs (partition 2 pairs+default?)
        convert (fn [[const form]]
                  (list (standardize const) form))
        most-of-it `(case (standardize ~expr) ~@(mapcat convert pairs))]
    (if (-> pairs+default? count even?)
      most-of-it
      (concat most-of-it [(last pairs+default?)]))))

例如,

(macroexpand-1 '(case-insensitive-case (test expression) 
                                       "Blam!" (1 + 1) 
                                       (whatever works)))
=> (clojure.core/case (lexer.core/standardize (test expression)) "blam!" (1 + 1) (whatever works))

assert中的standardize是必要的,因为lower-case会将事物变成字符串:

(clojure.string/lower-case 22)
=> "22"