2024 Clojure 调查问卷!中分享您的想法。

欢迎!有关如何使用本网站的更多信息,请参阅关于页面。

+1
ClojureScript
{{clojure.string/split}} 限制分割功能无法正确分割如下的字符串


(clojure.string/split "quaqb" #"q(?!u)") ; <- 匹配后面不是 'u' 的 'q'
;;=> ["qua" "b"]

(clojure.string/split "quaqb" #"q(?!u)" 2)
;;=> ["" "uaqb"]


第一种情况的结果是我们预期的,但第二种情况的结果是错误的。
这是因为,如果有限制,它将使用自己的算法而不是 JavaScript 的 {{String.prototype.split}} 函数来分割字符串。
而这个算法在使用正则表达式中的 [前瞻或后顾](https://regexper.cn/lookaround.html) 时存在问题。


;; clojure.string/split
(let [re #"q(?!u)"]
  (loop [s "quaqb"
         limit 2
         parts []]
    (if (= 1 limit)
         (conj parts s)
           
           (let [m (re-find re s)
                   (if-not (nil? m)
                          (let [index (.indexOf s m)
                                  (recur (.substring s (+ index (count m)))
                                       (dec limit)
                                       (conj parts (.substring s 0 index))))))))
;;=> ["" "uaqb"]

(re-find #"q(?!u)" "quaqb") ; <- 1!
;; => "q"

(.indexOf "quaqb" "q") ; <- 2!
;;=> 0


我们应该从 JavaScript 的 {{RegExp.prototype.exec}} 函数中获取索引,而不是计算索引。


;; clojure.string/split
(let [re #"q(?!u)"]
  (loop [s "quaqb"
         limit 2
         parts []]
    (if (= 1 limit)
         (conj parts s)
      (let [m (.exec re s]
           (let [m (re-find re s)
            (let [index (.-index m]
              (recur (.substring s (+ index (count (aget m 0))))
                                  (recur (.substring s (+ index (count m)))
                                       (dec limit)
                                       (conj parts (.substring s 0 index))))))))
;;=> ["qua" "b"]


                        i tested on V8, Spidermonkey, Nashorn.

6 答案

0

评论由:vmfhrmfoaj 发布

添加补丁

0

评论由:vmfhrmfoaj 发布

我更新了补丁以更改测试

0

评论由:vmfhrmfoaj 发布

我更新了补丁以修复边缘情况

0

评论由:vmfhrmfoaj 发布

我更新了补丁以修复错误并添加测试
很抱歉连续更新补丁,我以为这很简单)

0

评论由:vmfhrmfoaj 发布

更新补丁

0
参考:[https://clojure.atlassian.net/browse/CLJS-2528](https://clojure.atlassian.net/browse/CLJS-2528)(由 vmfhrmfoaj 提出)
...