2014-10-30 36 views
5

我在學習長生不老藥的過程中,跨越東西,沒有任何意義,我來到的二進制表示...返回與string.replace串

我試圖刪除標點

"Freude schöner Götterfunken" |> String.replace(~r/[^\s\w]/, "") #=> <<70, 114, 101, 117, 100, 101, 32, 115, 99, 104, 195, 110, 101, 114, 32, 71, 195, 116, 116, 101, 114, 102, 117, 110, 107, 101, 110>> 
"Freude schöner Götterfunken" |> String.replace(~r/[^\w]/, "") #=> <<70, 114, 101, 117, 100, 101, 32, 115, 99, 104, 195, 110, 101, 114, 32, 71, 195, 116, 116, 101, 114, 102, 117, 110, 107, 101, 110>> 
"Freude schöner Götterfunken" |> String.replace(~r/\p{P}/, "") #=> <<70, 114, 101, 117, 100, 101, 32, 115, 99, 104, 195, 110, 101, 114, 32, 71, 195, 116, 116, 101, 114, 102, 117, 110, 107, 101, 110>> 
"Freude schöner Götterfunken" |> String.replace(~r/\s/, "") #=> FreudeschönerGötterfunken 
"Hi my name is bob" |> String.replace(~r/\w/, "") #=> " " 
Regex.run(~r/[^\w]/, "Freude schöner Götterfunken") #=> [<<182>>] 

這看起來像一個錯誤,但作爲一個noob我假設無知。爲什麼不是替換返回字符串?

回答

17

您說得對,String.replace/2沒有返回字符串,因爲Elixir將字符串定義爲utf-8編碼的二進制文件。但是,這不是一個錯誤,因爲Elixir希望你傳遞或執行有效的參數操作,因爲它不會驗證所有結果(因爲代價昂貴)。

例如,如果您將以上任何一個二進制文件傳遞給String.downcase/1,Elixir將壓倒它所知道的部分,忽略其餘部分。它的工作原因是因爲UTF-8自動同步,所以如果我們看到奇怪的東西,我們可以跳過奇怪的字節並繼續進行操作。

換句話說,Elixir中的字符串處理的理念是在邊界進行驗證(例如打開文件,進行I/O或從數據庫讀取時),並假設我們正在使用和執行有效操作。

好吧,說了這麼多,爲什麼你的代碼不起作用?原因是你的regex沒有啓用unicode。讓我們添加的u修改則:

iex> "Freude schöner Götterfunken" |> String.replace(~r/[^\s\w]/u, "") 
"Freude schöner Götterfunken" 

那麼,它並不能解決你的問題,但至少結果是有效的。 Reading about unicode categories here意味着我們無法真正用unicode屬性解決這個問題,因爲在您的示例中ö是與\p{L}屬性匹配的單個代碼點。

也許在這種情況下,最簡單的解決方案,假設你只想解決它的德國人,是剛剛穿越二元保持字節< = 127.喜歡的東西:

iex> for <<x <- "Freude schöner Götterfunken">>, x <= 127, into: "", do: <<x>> 
"Freude schner Gtterfunken" 

如果你想要一個更完整的解決方案,你應該看看unicode音譯。

+0

真棒回答!感謝您的詳細解釋。閱讀文檔時,我錯過了修改器。 – matmer 2014-10-30 21:20:19

0

String.replace正在返回一個「字符串」,但雙引號字符串實際上存儲爲Elixir中的二進制文件。出於某種原因,輸出不能以常規字符串的形式顯示,因此,它回退到顯示二進制表示。

+1

「出於某種原因」在這裏:http://elixir-lang.org/getting_started/6.html#6.3-char-lists。請注意以下句子:「(注意,如果任何字符超出ASCII範圍,iex將僅輸出代碼點)。」由於@matmer的字符超出了ASCII範圍,整個事件都顯示爲代碼點。 – 2014-11-04 19:29:16