在 Clojure 中修剪不可打印字符的一般方法

Des*_*ong 6 string trim clojure string-matching zero-width-space

我遇到了一个错误,我无法将两个看似“相同”的字符串匹配在一起。例如,以下两个字符串无法匹配:“sample”和“?sample”。

要复制该问题,可以在 Clojure 中运行以下命令。

(= "sample" "?sample") ; returns false
Run Code Online (Sandbox Code Playgroud)

经过一个小时的沮丧调试,我发现第二个字符串前面有一个零宽度的空间!通过退格从这个特定的例子中删除它是微不足道的。但是,我有一个匹配的字符串数据库,似乎有多个字符串面临这个问题。我的问题是:是否有一种通用的方法可以在 Clojure 中修剪零宽度空格?

我试过的一些方法:

(count (clojure.string/trim "?abc")) ; returns 4
Run Code Online (Sandbox Code Playgroud)
(count (clojure.string/replace "?abc" #"\s" "")) ; returns 4
Run Code Online (Sandbox Code Playgroud)

这个线程从 JavaScript 字符串删除零宽度空格字符确实提供了一个在这个例子中工作的正则表达式解决方案,即

(count (clojure.string/replace "?abc" #"[\u200B-\u200D\uFEFF]" "")) ; returns 3
Run Code Online (Sandbox Code Playgroud)

但是,正如帖子本身所述,还有许多其他潜在的 ascii 字符可能是不可见的。所以我仍然很感兴趣,如果有一种更通用的方法不依赖于列出所有可能的不可见 unicode 符号。

Rul*_*lle 4

我相信,你所指的是所谓的不可打印字符。基于Java 中的这个答案#"\\p{C}",您可以将正则表达式作为模式传递给replace传递给:

\n
(defn remove-non-printable-characters [x]\n  (clojure.string/replace x #"\\p{C}" ""))\n
Run Code Online (Sandbox Code Playgroud)\n

但是,这将删除换行符,例如\\n。因此,为了保留这些字符,我们需要一个更复杂的正则表达式:

\n
(defn remove-non-printable-characters [x]\n  (clojure.string/replace x #"[\\p{C}&&^(\\S)]" ""))\n
Run Code Online (Sandbox Code Playgroud)\n

此函数将删除不可打印的字符。让我们测试一下:

\n
(= "sample" "\xe2\x80\x8bsample")\n;; => false\n\n(= (remove-non-printable-characters "sample")\n   (remove-non-printable-characters "\xe2\x80\x8bsample"))\n;; => true\n\n(remove-non-printable-characters "sam\\nple")\n;; => "sam\\nple"\n
Run Code Online (Sandbox Code Playgroud)\n

该模式在这里\\p{C}讨论模式。

\n