Clojure中使用正则表达式的两种方法

一直以来我都不知道Clojure里面的正则表达式有两种语法, 我一直以为只有一种, 那就是Java的语法, 因为Clojure根本没有自己的正则表达式引擎, 而是完全依赖于host, 如果是JVM就是Java的语法, 如果是Javascript虚拟机, 那就是Javascript的语法.

其实Clojure这里做一个小小的优化, 那就是#语法, 例子:

 
      (re-find #"\r\ncode:hide[\s\S]*?code:end\r\n" text)
 

节省了几个反斜线, 注意这不符合Java的语法, Java中\s \S都必须对反斜线进行转义, 因为\s \S不是合法的转义字符.

合法的只有 \b \t \n \f \r \" \' \\.

而Clojure这里优化了一下, 让\s不用加一个斜线, 如果是Java的话应该是

 
        Pattern p = Pattern.compile("\r\ncode:hide[\\s\\S]*?code:end\r\n"); 
 

当然要在Clojure中使用Java的正则表达式语法也是可以的, 要加一个re-pattern

 
      (re-find (re-pattern "\r\ncode:hide[\\s\\S]*?code:end\r\n") text)
 

难怪我的正则表达式有时候有效有时候无效, 一直以为是自己的写法有问题, 原来是对象弄错了. 这个小的改进固然是方便了一些, 但是仍然增加了学习成本, 而且对于没有耐心看文档的人, 很容易先入为主, 很容易忽略这些细节, 再加上这个改进并不是完全的改头换面, 所以即使在#语法中使用Java的格式, 也并不是任何时候都出错, 这就更加增加了迷惑性, 很可能一个人用了很久都没发现自己用的是错误的语法. 我也是刚刚才发现.