檢視原始碼 字串 (Elixir v1.16.2)

Elixir 中的字串是以 UTF-8 編碼的二進位資料。

Elixir 中的字串是一連串的 Unicode 字元,通常寫在雙引號內,例如 "hello""héllò"

如果字串本身必須包含雙引號,則必須使用反斜線來跳脫雙引號,例如:"this is a string with \"double quotes\""

你可以使用 <>/2 算子來串接兩個字串

iex> "hello" <> " " <> "world"
"hello world"

此模組中的函式會根據 Unicode 標準,版本 15.1.0 來運作。

內插

Elixir 中的字串也支援內插。這允許你使用 #{} 語法將一些值置於字串中間

iex> name = "joe"
iex> "hello #{name}"
"hello joe"

任何 Elixir 表達式都可以在內插中使用。如果給定字串,則會原樣內插字串。如果給定任何其他值,Elixir 會嘗試使用 String.Chars 協定將其轉換為字串。例如,這允許從內插中輸出整數

iex> "2 + 2 = #{2 + 2}"
"2 + 2 = 4"

如果你要內插的值無法轉換為字串,因為它沒有人類可讀的文字表示形式,則會引發協定錯誤。

跳脫字元

除了允許使用反斜線跳脫雙引號之外,字串也支援下列跳脫字元

  • \0 - Null 位元組
  • \a - 鈴聲
  • \b - 退格
  • \t - 水平標籤
  • \n - 換行符號(新行)
  • \v - 垂直標籤
  • \f - 表單進紙
  • \r - 回車
  • \e - 指令跳脫
  • \s - 空格
  • \# - 傳回 # 字元本身,略過內插
  • \\ - 單一反斜線
  • \xNN - 十六進位 NN 所表示的位元組
  • \uNNNN - NNNN 所表示的 Unicode 編碼點
  • \u{NNNNNN} - NNNNNN 所表示的 Unicode 編碼點

請注意,通常不建議在 Elixir 字串中使用 \xNN,因為引入無效的位元組序列會使字串無效。如果您必須使用十六進位表示法來引入字元,最好使用 Unicode 編碼點,例如 \uNNNN。事實上,在進行低階字串操作時,了解 Unicode 編碼點至關重要,因此讓我們接下來詳細探討它們。

Unicode 和編碼點

為了促進多種語言之間的電腦有意義的溝通,需要一個標準,以便一台電腦上的 1 和 0 在傳輸到另一台電腦時具有相同的意義。Unicode 標準作為我們所知幾乎所有字元的官方註冊表:這包括古典和歷史文本、表情符號以及格式化和控制字元。

Unicode 將其庫中的所有字元整理成編碼表,每個字元都有一個唯一的數字索引。此數字索引稱為編碼點。

在 Elixir 中,您可以在字元文字前面使用 ? 來顯示其編碼點

iex> ?a
97
iex> 
322

請注意,大多數 Unicode 編碼表會以其十六進位 (hex) 表示法來表示編碼點,例如 97 轉換為十六進位的 0061,我們可以使用 \u 跳脫字元後接其編碼點數字來表示 Elixir 字串中的任何 Unicode 字元

iex> "\u0061" === "a"
true
iex> 0x0061 = 97 = ?a
97

十六進位表示法也可以幫助您查詢有關編碼點的資訊,例如 https://codepoints.net/U+0061 有一個關於小寫 a(又稱編碼點 97)的資料表。請記住,您可以透過呼叫 Integer.to_string/2 來取得數字的十六進位表示法

iex> Integer.to_string(?a, 16)
"61"

UTF-8 編碼與編碼方式

現在我們了解 Unicode 標準是什麼,以及什麼是碼點,我們終於可以討論編碼方式了。碼點是我們儲存的內容,而編碼方式則處理我們如何儲存的:編碼方式是一種實作。換句話說,我們需要一種機制將碼點數字轉換成位元組,以便將它們儲存在記憶體中、寫入磁碟等等。

Elixir 使用 UTF-8 編碼其字串,表示碼點編碼為一系列 8 位元組。UTF-8 是一種可變寬度字元編碼,使用一到四個位元組儲存每個碼點。它能夠編碼所有有效的 Unicode 碼點。我們來看一個範例

iex> string = "héllo"
"héllo"
iex> String.length(string)
5
iex> byte_size(string)
6

儘管上面的字串有 5 個字元,但它使用了 6 個位元組,因為兩個位元組用於表示字元 é

字形群集

這個模組也使用字形群集的概念(從現在開始稱為字形)。字形可能包含多個碼點,這些碼點可能被讀者視為單一字元。例如,「é」可以表示為單一的「帶銳音符的 e」碼點,如上面字串 "héllo" 中所示,或表示為字母「e」後接「組合銳音符」(兩個碼點)

iex> string = "\u0065\u0301"
"é"
iex> byte_size(string)
3
iex> String.length(string)
1
iex> String.codepoints(string)
["e", "́"]
iex> String.graphemes(string)
["é"]

儘管它看起來與之前視覺上相同,但上面的範例由兩個字元組成,使用者視為一個字元。

字形也可以是兩個字元,某些語言將其解釋為一個字元。例如,某些語言可能將「ch」視為一個單一字元。但是,由於此資訊取決於區域設定,因此此模組不會考慮它。

一般來說,此模組中的函式依賴於 Unicode 標準,但不包含任何特定區域設定的行為。有關字形的更多資訊,請參閱 Unicode 標準附錄 #29

有關將二進位制轉換為不同編碼和 Unicode 正規化機制的資訊,請參閱 Erlang 的 :unicode 模組。

字串與二進位制運算

為了根據 Unicode 標準執行,此模組中的許多函式以線性時間執行,因為它們需要考慮適當的 Unicode 碼點來遍歷整個字串。

例如,String.length/1 會隨著輸入的增加而花費更長的時間。另一方面,Kernel.byte_size/1 總是以常數時間執行(即無論輸入大小如何)。

這表示與直接使用二進位制的較低層級運算相比,使用此模組中的函式通常會有效能成本

二進制語法 <<>> 中也提供 utf8 修飾詞。它可用於比對二進制/字串中的編碼點

iex> <<eacute::utf8>> = "é"
iex> eacute
233

您也可以透過呼叫 String.to_charlist/1,將字串完全轉換成整數編碼點清單,在 Elixir 中稱為「字元清單」

iex> String.to_charlist("héllo")
[104, 233, 108, 108, 111]

如果您想要查看字串的底層位元組,而不是其編碼點,一個常見的技巧是將空位元組 <<0>> 串聯到它

iex> "héllo" <> <<0>>
<<104, 195, 169, 108, 108, 111, 0>>

或者,您可以透過傳遞選項給 IO.inspect/2 來檢視字串的二進制表示

IO.inspect("héllo", binaries: :as_binaries)
#=> <<104, 195, 169, 108, 108, 111>>

自我同步

UTF-8 編碼是自我同步的。這表示如果遇到格式錯誤的資料(即根據編碼定義不可能存在的資料),只需要拒絕一個編碼點。

此模組仰賴此行為來忽略此類無效字元。例如,即使將無效編碼點傳入 length/1,它仍會傳回正確的結果。

換句話說,此模組預期無效資料會在其他地方被偵測到,通常是在從外部來源擷取資料時。例如,從資料庫讀取字串的驅動程式將負責檢查編碼的有效性。 String.chunk/2 可用於將字串分解成有效和無效的部分。

編譯二進制模式

此模組中的許多函式都使用模式。例如, String.split/3 可以根據模式將字串分割成多個字串。此模式可以是字串、字串清單或編譯模式

iex> String.split("foo bar", " ")
["foo", "bar"]

iex> String.split("foo bar!", [" ", "!"])
["foo", "bar", ""]

iex> pattern = :binary.compile_pattern([" ", "!"])
iex> String.split("foo bar!", pattern)
["foo", "bar", ""]

當相同比對會重複執行多次時,編譯模式會很有用。但請注意,編譯模式無法儲存在模組屬性中,因為模式是在執行時產生,且無法在編譯時保留。

摘要

類型

以 UTF-8 編碼的單一 Unicode 碼點。可能是一或多個位元組。

讀者可能視為單一字元的多個碼點

用於 replace/4split/3 等函數中的模式。

t()

以 UTF-8 編碼的二進位。

函數

傳回給定 UTF-8 字串位置 上的字元。如果 位置 大於 字串 長度,則傳回 nil

計算兩個字串之間的 bag 距離。

根據 模式 將給定字串中的第一個字元轉換為大寫,其餘字元轉換為小寫。

將字串分割成具有共同特徵的字元區塊。

傳回以字串編碼的碼點清單。

搜尋 字串 是否包含任何給定的 內容

根據 模式 將給定字串中的所有字元轉換為小寫。

傳回 主旨 字串重複 n 次的結果。

如果 字串 以任何給定的字尾結尾,則傳回 true

如果 字串1字串2 正規相等,則傳回 true

傳回 UTF-8 字串中的第一個字元,如果字串為空則傳回 nil

根據擴充字元集演算法傳回字串中的 Unicode 字元。

計算兩個字串之間的 Jaro 距離(相似度)。

傳回 UTF-8 字串中的最後一個字元,如果字串為空則傳回 nil

傳回 UTF-8 字串中的 Unicode 字元數。

檢查 字串 是否符合給定的正規表示式。

傳回表示編輯指令碼的關鍵字清單。

傳回字串中的下一個碼點。

傳回字串中的下一個字元。

字串 中的所有字元轉換為由 形式 識別的 Unicode 正規形式。

傳回一個新的字串,以 填補 中的元素填補開頭。

傳回一個新的字串,以 填補 中的元素填補結尾。

檢查字串是否只包含最多 字元限制 的可列印字元。

傳回一個新的字串,以 取代 取代 主旨模式 的出現。

傳回一個新的字串,以 取代 ("�" 為預設值) 取代所有無效位元組。

取代 取代 字串相符 的所有開頭出現。

如果 字串 中的前綴與 相符 相符,則以 取代 取代前綴。

如果 字串 中的後綴與 相符 相符,則以 取代 取代後綴。

取代 取代 字串相符 的所有結尾出現。

反轉給定字串中的字素。

傳回從範圍開頭給定的偏移量到範圍結尾給定的偏移量之間的子字串。

傳回從偏移量 起始 開始且長度為 長度 的子字串。

在每個 Unicode 空白出現處將字串分割為子字串,並忽略開頭和結尾的空白。空白群組視為單一出現。分割不會發生在不換行空白上。

根據模式將字串分割成數個部分。

在指定偏移量處將字串分割為兩個部分。當給定的偏移量為負數時,位置會從字串結尾開始計算。

傳回一個可列舉物件,依需求將字串分割。

如果 string 以任何給定的前綴開頭,則回傳 true

將字串轉換為現有的原子或建立新的原子。

將字串轉換為字元清單。

將字串轉換為現有的原子,如果原子不存在,則會引發錯誤。

回傳一個浮點數,其文字表示為 string

回傳一個整數,其文字表示為 string

回傳一個整數,其文字表示為 string,底數為 base

回傳一個字串,其中已移除所有前導和尾隨的 Unicode 空白。

回傳一個字串,其中已移除所有前導和尾隨的 to_trim 字元。

回傳一個字串,其中已移除所有前導的 Unicode 空白。

回傳一個字串,其中已移除所有前導的 to_trim 字元。

回傳一個字串,其中已移除所有尾隨的 Unicode 空白。

回傳一個字串,其中已移除所有尾隨的 to_trim 字元。

根據 mode 將給定字串中的所有字元轉換為大寫。

檢查 string 是否只包含有效字元。

類型

@type codepoint() :: t()

以 UTF-8 編碼的單一 Unicode 碼點。可能是一或多個位元組。

@type grapheme() :: t()

讀者可能視為單一字元的多個碼點

@type pattern() ::
  t() | [nonempty_binary()] | (compiled_search_pattern :: :binary.cp())

用於 replace/4split/3 等函數中的模式。

必須為下列其中一項

@type t() :: binary()

以 UTF-8 編碼的二進位。

對於分析工具而言,String.t()binary() 類型是等效的。不過,對於閱讀文件的人而言,String.t() 表示它是 UTF-8 編碼的二進位資料。

函式

@spec at(t(), integer()) :: grapheme() | nil

傳回給定 UTF-8 字串位置 上的字元。如果 位置 大於 字串 長度,則傳回 nil

範例

iex> String.at("elixir", 0)
"e"

iex> String.at("elixir", 1)
"l"

iex> String.at("elixir", 10)
nil

iex> String.at("elixir", -1)
"r"

iex> String.at("elixir", -10)
nil
連結到此函式

bag_distance(字串1, 字串2)

檢視原始碼 (自 1.8.0 起)
@spec bag_distance(t(), t()) :: float()

計算兩個字串之間的 bag 距離。

傳回介於 0 到 1 之間的浮點值,代表 string1string2 之間的 bag 距離。

bag 距離旨在作為兩個字串之間距離的有效近似值,以快速排除差異極大的字串。

此演算法概述於 Ilaria Bartolini、Paolo Ciaccia 和 Marco Patella 的「使用近似距離進行度量樹字串比對」論文中。

範例

iex> String.bag_distance("abc", "")
0.0
iex> String.bag_distance("abcd", "a")
0.25
iex> String.bag_distance("abcd", "ab")
0.5
iex> String.bag_distance("abcd", "abc")
0.75
iex> String.bag_distance("abcd", "abcd")
1.0
連結到此函式

capitalize(字串, 模式 \\ :default)

檢視原始碼
@spec capitalize(t(), :default | :ascii | :greek | :turkic) :: t()

根據 模式 將給定字串中的第一個字元轉換為大寫,其餘字元轉換為小寫。

mode 可以是 :default:ascii:greek:turkic:default 模式考量 Unicode 標準中概述的所有非條件轉換。 :ascii 僅將 A 到 Z 的字母大寫。 :greek 包含希臘文中找到的內容敏感對應。 :turkic 正確處理帶有無點變體的字母 i

另請參閱 upcase/2capitalize/2 以取得其他轉換。如果您想要此函式的變體,不會將字串的其餘部分轉換為小寫,請參閱 Erlang 的 :string.titlecase/1

範例

iex> String.capitalize("abcd")
"Abcd"
iex> String.capitalize("ABCD")
"Abcd"

iex> String.capitalize("fin")
"Fin"
iex> String.capitalize("olá")
"Olá"
@spec chunk(t(), :valid | :printable) :: [t()]

將字串分割成具有共同特徵的字元區塊。

特徵可以是兩個選項之一

  • :valid - 字串會分割成有效和無效字元序列的區塊

  • :printable - 字串會分割成可列印和不可列印字元序列的區塊

傳回一個二進位清單,每個二進位只包含一種字元。

如果給定的字串為空,則傳回一個空清單。

範例

iex> String.chunk(<<?a, ?b, ?c, 0>>, :valid)
["abc\0"]

iex> String.chunk(<<?a, ?b, ?c, 0, 0xFFFF::utf16>>, :valid)
["abc\0", <<0xFFFF::utf16>>]

iex> String.chunk(<<?a, ?b, ?c, 0, 0x0FFFF::utf8>>, :printable)
["abc", <<0, 0x0FFFF::utf8>>]
@spec codepoints(t()) :: [codepoint()]

傳回以字串編碼的碼點清單。

若要以其自然整數表示法擷取碼點,請參閱 to_charlist/1。有關碼點和音位的詳細資訊,請參閱 String 模組文件。

範例

iex> String.codepoints("olá")
["o", "l", "á"]

iex> String.codepoints("оптими зации")
["о", "п", "т", "и", "м", "и", " ", "з", "а", "ц", "и", "и"]

iex> String.codepoints("ἅἪῼ")
["ἅ", "Ἢ", "ῼ"]

iex> String.codepoints("\u00e9")
["é"]

iex> String.codepoints("\u0065\u0301")
["e", "́"]
連結到此函式

contains?(字串, 內容)

檢視原始碼
@spec contains?(t(), [t()] | pattern()) :: boolean()

搜尋 字串 是否包含任何給定的 內容

contents 可以是字串、字串清單或已編譯的樣式。如果 contents 是清單,此函式會搜尋 contents 中的任何字串是否為 string 的一部分。

在清單中搜尋字串

如果您想要檢查 string 是否列在 contents 中,其中 contents 是清單,請改用 Enum.member?(contents, string)

範例

iex> String.contains?("elixir of life", "of")
true
iex> String.contains?("elixir of life", ["life", "death"])
true
iex> String.contains?("elixir of life", ["death", "mercury"])
false

引數也可以是已編譯的模式

iex> pattern = :binary.compile_pattern(["life", "death"])
iex> String.contains?("elixir of life", pattern)
true

空字串永遠會相符

iex> String.contains?("elixir of life", "")
true
iex> String.contains?("elixir of life", ["", "other"])
true

空清單永遠不會相符

iex> String.contains?("elixir of life", [])
false

iex> String.contains?("", [])
false

請注意,此函式可以在音位邊界內或跨音位邊界進行比對。例如,音位「é」是由字元「e」和銳音符號組成。以下會傳回 true

iex> String.contains?(String.normalize("é", :nfd), "e")
true

然而,如果「é」由單一字元「帶銳音符號的 e」表示,則會傳回 false

iex> String.contains?(String.normalize("é", :nfc), "e")
false
連結到此函式

downcase(字串, 模式 \\ :default)

檢視原始碼
@spec downcase(t(), :default | :ascii | :greek | :turkic) :: t()

根據 模式 將給定字串中的所有字元轉換為小寫。

模式可能是 :default:ascii:greek:turkic:default 模式會考量 Unicode 標準中概述的所有非條件轉換。 :ascii 僅將字母 A 到 Z 轉換成小寫。 :greek 包含在希臘文中找到的內容敏感對應。 :turkic 正確處理帶有非點變體的字母 i。

另請參閱 upcase/2capitalize/2 以進行其他轉換。

範例

iex> String.downcase("ABCD")
"abcd"

iex> String.downcase("AB 123 XPTO")
"ab 123 xpto"

iex> String.downcase("OLÁ")
"olá"

:ascii 模式會忽略 Unicode 字元,並在您知道字串僅包含 ASCII 字元時提供效能更高的實作

iex> String.downcase("OLÁ", :ascii)
"olÁ"

:greek 模式會正確處理希臘文中內容敏感的 sigma

iex> String.downcase("ΣΣ")
"σσ"

iex> String.downcase("ΣΣ", :greek)
"σς"

:turkic 會正確處理帶有非點變體的字母 i

iex> String.downcase("Iİ")
"ii̇"

iex> String.downcase("Iİ", :turkic)
"ıi"
@spec duplicate(t(), non_neg_integer()) :: t()

傳回 主旨 字串重複 n 次的結果。

由編譯器內嵌。

範例

iex> String.duplicate("abc", 0)
""

iex> String.duplicate("abc", 1)
"abc"

iex> String.duplicate("abc", 2)
"abcabc"
連結到此函式

ends_with?(字串, 字尾)

檢視原始碼
@spec ends_with?(t(), t() | [t()]) :: boolean()

如果 字串 以任何給定的字尾結尾,則傳回 true

後綴可以是單一後綴或後綴清單。

範例

iex> String.ends_with?("language", "age")
true
iex> String.ends_with?("language", ["youth", "age"])
true
iex> String.ends_with?("language", ["youth", "elixir"])
false

空後綴永遠會相符

iex> String.ends_with?("language", "")
true
iex> String.ends_with?("language", ["", "other"])
true
連結到此函式

equivalent?(字串1, 字串2)

檢視原始碼
@spec equivalent?(t(), t()) :: boolean()

如果 字串1字串2 正規相等,則傳回 true

它會在比較字串前對其執行正規形式正規分解 (NFD)。此函式等同於

String.normalize(string1, :nfd) == String.normalize(string2, :nfd)

如果您打算多次比較多個字串,您可以先將它們正規化,然後直接比較它們,以避免多次正規化傳遞。

範例

iex> String.equivalent?("abc", "abc")
true

iex> String.equivalent?("man\u0303ana", "mañana")
true

iex> String.equivalent?("abc", "ABC")
false

iex> String.equivalent?("nø", "nó")
false
@spec first(t()) :: grapheme() | nil

傳回 UTF-8 字串中的第一個字元,如果字串為空則傳回 nil

範例

iex> String.first("elixir")
"e"

iex> String.first("եոգլի")
"ե"

iex> String.first("")
nil
@spec graphemes(t()) :: [grapheme()]

根據擴充字元集演算法傳回字串中的 Unicode 字元。

演算法概述於 Unicode 標準附錄 #29,Unicode 文字分段 中。

有關碼點和音位的詳細資訊,請參閱 字串 模組文件。

範例

iex> String.graphemes("Ńaïve")
["Ń", "a", "ï", "v", "e"]

iex> String.graphemes("\u00e9")
["é"]

iex> String.graphemes("\u0065\u0301")
["é"]
連結到此函式

jaro_distance(字串1, 字串2)

檢視原始碼
@spec jaro_distance(t(), t()) :: float()

計算兩個字串之間的 Jaro 距離(相似度)。

傳回介於 0.0(等於沒有相似性)和 1.0(完全相符)之間的浮點值,表示 string1string2 之間的 Jaro 距離。

Jaro 距離量度是針對短字串(例如人名)設計,且最適合短字串。Elixir 本身使用此函式提供「您要找的是不是?」功能。例如,當您在模組中呼叫函式時,如果函式名稱有錯字,我們會嘗試根據 jaro_distance/2 分數建議最相似的函式名稱(如果有)。

範例

iex> String.jaro_distance("Dwayne", "Duane")
0.8222222222222223
iex> String.jaro_distance("even", "odd")
0.0
iex> String.jaro_distance("same", "same")
1.0
@spec last(t()) :: grapheme() | nil

傳回 UTF-8 字串中的最後一個字元,如果字串為空則傳回 nil

它會遍歷整個字串,找出最後一個音位。

範例

iex> String.last("")
nil

iex> String.last("elixir")
"r"

iex> String.last("եոգլի")
"ի"
@spec length(t()) :: non_neg_integer()

傳回 UTF-8 字串中的 Unicode 字元數。

範例

iex> String.length("elixir")
6

iex> String.length("եոգլի")
5
連結到此函式

match?(字串, 正規表示式)

檢視原始碼
@spec match?(t(), Regex.t()) :: boolean()

檢查 字串 是否符合給定的正規表示式。

範例

iex> String.match?("foo", ~r/foo/)
true

iex> String.match?("bar", ~r/foo/)
false

Elixir 也提供基於文字的比對運算子 =~/2 和函式 Regex.match?/2,作為測試字串是否符合正規表示式的替代方案。

連結到此函式

myers_difference(字串1, 字串2)

檢視原始碼 (自 1.3.0 起)
@spec myers_difference(t(), t()) :: [{:eq | :ins | :del, t()}]

傳回表示編輯指令碼的關鍵字清單。

查看 List.myers_difference/2 以取得更多資訊。

範例

iex> string1 = "fox hops over the dog"
iex> string2 = "fox jumps over the lazy cat"
iex> String.myers_difference(string1, string2)
[eq: "fox ", del: "ho", ins: "jum", eq: "ps over the ", del: "dog", ins: "lazy cat"]
@spec next_codepoint(t()) :: {codepoint(), t()} | nil

傳回字串中的下一個碼點。

結果是一個元組,包含碼點和字串的其餘部分,或在字串已達尾端時為 nil

String 模組中的其他函式一樣,next_codepoint/1 可處理無效的 UTF-8 二進位檔。如果字串以不符合 UTF-8 編碼的位元組序列開頭,則傳回元組的第一個元素是包含第一個位元組的二進位檔。

範例

iex> String.next_codepoint("olá")
{"o", "lá"}

iex> invalid = "\x80\x80OK" # first two bytes are invalid in UTF-8
iex> {_, rest} = String.next_codepoint(invalid)
{<<128>>, <<128, 79, 75>>}
iex> String.next_codepoint(rest)
{<<128>>, "OK"}

比較二進制模式配對

二進制模式配對提供類似的方式來分解字串

iex> <<codepoint::utf8, rest::binary>> = "Elixir"
"Elixir"
iex> codepoint
69
iex> rest
"lixir"

儘管不完全相等,因為 codepoint 以整數形式出現,而且模式不會配對無效的 UTF-8。

然而,二進制模式配對更簡單且更有效率,因此請選擇更適合您使用案例的選項。

@spec next_grapheme(t()) :: {grapheme(), t()} | nil

傳回字串中的下一個字元。

結果是一個包含字素和字串剩餘部分的元組,或者在字串已達其結尾時為 nil

範例

iex> String.next_grapheme("olá")
{"o", "lá"}

iex> String.next_grapheme("")
nil
連結到此函式

normalize(字串, 形式)

檢視原始碼
@spec normalize(t(), :nfd | :nfc | :nfkd | :nfkc) :: t()

字串 中的所有字元轉換為由 形式 識別的 Unicode 正規形式。

無效的 Unicode codepoint 會被略過,而字串的剩餘部分會被轉換。如果您希望演算法在無效的 codepoint 上停止並傳回,請改用 :unicode.characters_to_nfd_binary/1:unicode.characters_to_nfc_binary/1:unicode.characters_to_nfkd_binary/1:unicode.characters_to_nfkc_binary/1

正規化形式 :nfkc:nfkd 不應盲目應用於任意文字。因為它們會抹除許多格式化區別,所以它們會阻止與許多舊有字元集進行往返轉換。

形式

支援的形式為

  • :nfd - 正規化形式正規分解。字元依據正規等價性分解,而且多個組合字元會以特定順序排列。

  • :nfc - 正規化形式正規合成。字元會分解,然後依據正規等價性重新合成。

  • :nfkd - 正規化形式相容性分解。字元依據相容性等價性分解,而且多個組合字元會以特定順序排列。

  • :nfkc - 正規化形式相容性合成。字元會分解,然後依據相容性等價性重新合成。

範例

iex> String.normalize("yêṩ", :nfd)
"yêṩ"

iex> String.normalize("leña", :nfc)
"leña"

iex> String.normalize("fi", :nfkd)
"fi"

iex> String.normalize("fi", :nfkc)
"fi"
連結到此函式

pad_leading(字串, 計數, 填補 \\ [" "])

檢視原始碼
@spec pad_leading(t(), non_neg_integer(), t() | [t()]) :: t()

傳回一個新的字串,以 填補 中的元素填補開頭。

傳遞字串清單作為 padding 會為每個遺失的項目取用清單中的其中一個元素。如果清單比插入項目的數量還短,填補會從清單的開頭重新開始。傳遞字串 padding 等同於傳遞其中的字素清單。如果沒有給定 padding,它會預設為空白。

count 小於或等於 string 的長度時,會傳回給定的 string

如果給定的 padding 包含非字串元素,會引發 ArgumentError

範例

iex> String.pad_leading("abc", 5)
"  abc"

iex> String.pad_leading("abc", 4, "12")
"1abc"

iex> String.pad_leading("abc", 6, "12")
"121abc"

iex> String.pad_leading("abc", 5, ["1", "23"])
"123abc"
連結到此函式

pad_trailing(字串, 計數, 填補 \\ [" "])

檢視原始碼
@spec pad_trailing(t(), non_neg_integer(), t() | [t()]) :: t()

傳回一個新的字串,以 填補 中的元素填補結尾。

傳遞字串清單作為 padding 會為每個遺失的項目取用清單中的其中一個元素。如果清單比插入項目的數量還短,填補會從清單的開頭重新開始。傳遞字串 padding 等同於傳遞其中的字素清單。如果沒有給定 padding,它會預設為空白。

count 小於或等於 string 的長度時,會傳回給定的 string

如果給定的 padding 包含非字串元素,會引發 ArgumentError

範例

iex> String.pad_trailing("abc", 5)
"abc  "

iex> String.pad_trailing("abc", 4, "12")
"abc1"

iex> String.pad_trailing("abc", 6, "12")
"abc121"

iex> String.pad_trailing("abc", 5, ["1", "23"])
"abc123"
連結到此函式

printable?(字串, 字元限制 \\ :infinity)

檢視原始碼
@spec printable?(t(), 0) :: true
@spec printable?(t(), pos_integer() | :infinity) :: boolean()

檢查字串是否只包含最多 字元限制 的可列印字元。

將一個選用的 character_limit 作為第二個參數。如果 character_limit0,此函式會傳回 true

範例

iex> String.printable?("abc")
true

iex> String.printable?("abc" <> <<0>>)
false

iex> String.printable?("abc" <> <<0>>, 2)
true

iex> String.printable?("abc" <> <<0>>, 0)
true
連結到此函式

replace(主旨, 模式, 取代, 選項 \\ [])

檢視原始碼
@spec replace(t(), pattern() | Regex.t(), t() | (t() -> t() | iodata()), keyword()) ::
  t()

傳回一個新的字串,以 取代 取代 主旨模式 的出現。

subject 永遠是字串。

pattern 可以是字串、字串清單、正規表示式或已編譯的模式。

replacement 可以是字串或接收配對模式的函式,且必須傳回字串或 iodata 作為替換。

預設會替換所有出現,但此行為可透過 :global 選項控制;請參閱下方的「選項」區段。

選項

  • :global - (布林值) 如果 truepattern 的所有出現都會以 replacement 替換,否則只會替換第一次出現。預設為 true

範例

iex> String.replace("a,b,c", ",", "-")
"a-b-c"

iex> String.replace("a,b,c", ",", "-", global: false)
"a-b,c"

模式也可以是字串清單,而替換也可以是接收配對的函式

iex> String.replace("a,b,c", ["a", "c"], fn <<char>> -> <<char + 1>> end)
"b,b,d"

當模式是正規表示式時,可以在 replacement 字串中提供 \N\g{N} 來存取正規表示式中的特定擷取。

iex> String.replace("a,b,c", ~r/,(.)/, ",\\1\\g{1}")
"a,bb,cc"

請注意,我們必須跳脫反斜線跳脫字元 (亦即,我們使用 \\N 而不是 \N 來跳脫反斜線;\\g{N} 也是一樣)。透過提供 \0,可以在替換字串中注入整個配對。

也可以提供已編譯的模式

iex> pattern = :binary.compile_pattern(",")
iex> String.replace("a,b,c", pattern, "[]")
"a[]b[]c"

當提供空字串作為 模式 時,函式會將其視為每個字素之間的隱式空字串,且字串將會穿插。如果提供空字串作為 替換,則會傳回 主旨

iex> String.replace("ELIXIR", "", ".")
".E.L.I.X.I.R."

iex> String.replace("ELIXIR", "", "")
"ELIXIR"

請注意,此函式可以在字素邊界內或跨字素邊界替換。例如,取字素「é」,它由字元「e」和銳音符號組成。以下只會替換字母「e」,將重音符號移到字母「o」

iex> String.replace(String.normalize("é", :nfd), "e", "o")
"ó"

但是,如果「é」由單一字元「帶銳音符號的 e」表示,則它根本不會被替換

iex> String.replace(String.normalize("é", :nfc), "e", "o")
"é"
連結到此函式

replace_invalid(位元組, 取代 \\ "�")

檢視原始碼 (自 1.16.0 起)

傳回一個新的字串,以 取代 ("�" 為預設值) 取代所有無效位元組。

範例

iex> String.replace_invalid("asd" <> <<0xFF::8>>)
"asd�"

iex> String.replace_invalid("nem rán bề bề")
"nem rán bề bề"

iex> String.replace_invalid("nem rán b" <> <<225, 187>> <> " bề")
"nem rán b� bề"

iex> String.replace_invalid("nem rán b" <> <<225, 187>> <> " bề", "ERROR!")
"nem rán bERROR! bề"
連結到此函式

replace_leading(字串, 相符, 取代)

檢視原始碼
@spec replace_leading(t(), t(), t()) :: t()

取代 取代 字串相符 的所有開頭出現。

如果沒有出現,則傳回未更動的字串。

如果 比對"",此函式會引發 ArgumentError 例外:這是因為此函式會替換 string 開頭處 比對所有出現,而無法替換 "" 的「多個」出現。

範例

iex> String.replace_leading("hello world", "hello ", "")
"world"
iex> String.replace_leading("hello hello world", "hello ", "")
"world"

iex> String.replace_leading("hello world", "hello ", "ola ")
"ola world"
iex> String.replace_leading("hello hello world", "hello ", "ola ")
"ola ola world"

此函式可以在字素邊界跨越替換。請參閱 replace/3 以取得更多資訊和範例。

連結到此函式

replace_prefix(字串, 相符, 取代)

檢視原始碼
@spec replace_prefix(t(), t(), t()) :: t()

如果 字串 中的前綴與 相符 相符,則以 取代 取代前綴。

如果沒有比對,則傳回未更動的字串。如果 比對 是空字串 (""),則 替換 僅會附加在 string 之前。

範例

iex> String.replace_prefix("world", "hello ", "")
"world"
iex> String.replace_prefix("hello world", "hello ", "")
"world"
iex> String.replace_prefix("hello hello world", "hello ", "")
"hello world"

iex> String.replace_prefix("world", "hello ", "ola ")
"world"
iex> String.replace_prefix("hello world", "hello ", "ola ")
"ola world"
iex> String.replace_prefix("hello hello world", "hello ", "ola ")
"ola hello world"

iex> String.replace_prefix("world", "", "hello ")
"hello world"

此函式可以在字素邊界跨越替換。請參閱 replace/3 以取得更多資訊和範例。

連結到此函式

replace_suffix(字串, 相符, 取代)

檢視原始碼
@spec replace_suffix(t(), t(), t()) :: t()

如果 字串 中的後綴與 相符 相符,則以 取代 取代後綴。

如果沒有比對,則傳回未更動的字串。如果 比對 是空字串 (""),則 替換 僅會附加在 string 之後。

範例

iex> String.replace_suffix("hello", " world", "")
"hello"
iex> String.replace_suffix("hello world", " world", "")
"hello"
iex> String.replace_suffix("hello world world", " world", "")
"hello world"

iex> String.replace_suffix("hello", " world", " mundo")
"hello"
iex> String.replace_suffix("hello world", " world", " mundo")
"hello mundo"
iex> String.replace_suffix("hello world world", " world", " mundo")
"hello world mundo"

iex> String.replace_suffix("hello", "", " world")
"hello world"

此函式可以在字素邊界跨越替換。請參閱 replace/3 以取得更多資訊和範例。

連結到此函式

replace_trailing(字串, 相符, 取代)

檢視原始碼
@spec replace_trailing(t(), t(), t()) :: t()

取代 取代 字串相符 的所有結尾出現。

如果沒有出現,則傳回未更動的字串。

如果 比對"",此函式會引發 ArgumentError 例外:這是因為此函式會替換 string 結尾處 比對所有出現,而無法替換 "" 的「多個」出現。

範例

iex> String.replace_trailing("hello world", " world", "")
"hello"
iex> String.replace_trailing("hello world world", " world", "")
"hello"

iex> String.replace_trailing("hello world", " world", " mundo")
"hello mundo"
iex> String.replace_trailing("hello world world", " world", " mundo")
"hello mundo mundo"

此函式可以在字素邊界跨越替換。請參閱 replace/3 以取得更多資訊和範例。

@spec reverse(t()) :: t()

反轉給定字串中的字素。

範例

iex> String.reverse("abcd")
"dcba"

iex> String.reverse("hello world")
"dlrow olleh"

iex> String.reverse("hello ∂og")
"go∂ olleh"

請記住,反轉同一字串兩次並不一定會產生原始字串

iex> "̀e"
"̀e"
iex> String.reverse("̀e")
"è"
iex> String.reverse(String.reverse("̀e"))
"è"

在第一個範例中,重音符號在母音之前,因此被視為兩個字形。但是,當你反轉它一次時,你會得到母音後跟重音符號,這變成一個字形。再次反轉它將保持它為一個單一字形。

@spec slice(t(), Range.t()) :: t()

傳回從範圍開頭給定的偏移量到範圍結尾給定的偏移量之間的子字串。

如果範圍的開頭不是給定字串的有效偏移量,或者如果範圍是反向順序,則傳回 ""

如果範圍的開頭或結尾為負數,則會先遍歷整個字串,以將負數索引轉換為正數索引。

請記住,此函式使用 Unicode 字形,並將切片視為代表字形偏移量。如果你想以原始位元組分割,請改為查看 Kernel.binary_part/3Kernel.binary_slice/2

範例

iex> String.slice("elixir", 1..3)
"lix"
iex> String.slice("elixir", 1..10)
"lixir"

iex> String.slice("elixir", -4..-1)
"ixir"
iex> String.slice("elixir", -4..6)
"ixir"
iex> String.slice("elixir", -100..100)
"elixir"

對於 start > stop 的範圍,你需要明確地將它們標記為遞增

iex> String.slice("elixir", 2..-1//1)
"ixir"
iex> String.slice("elixir", 1..-2//1)
"lixi"

你可以使用 ../0 作為 0..-1//1 的捷徑,它會原樣傳回整個字串

iex> String.slice("elixir", ..)
"elixir"

步長可以是任何正數。例如,要取得字串的每 2 個字元

iex> String.slice("elixir", 0..-1//2)
"eii"

如果第一個位置在字串結尾之後或在範圍的最後一個位置之後,它會傳回一個空字串

iex> String.slice("elixir", 10..3//1)
""
iex> String.slice("a", 1..1500)
""
連結到此函式

slice(字串, 起始, 長度)

檢視原始碼
@spec slice(t(), integer(), non_neg_integer()) :: grapheme()

傳回從偏移量 起始 開始且長度為 長度 的子字串。

如果偏移量大於字串長度,則傳回 ""

請記住,此函式使用 Unicode 字形,並將切片視為代表字形偏移量。如果你想以原始位元組分割,請改為查看 Kernel.binary_part/3Kernel.binary_slice/3

範例

iex> String.slice("elixir", 1, 3)
"lix"

iex> String.slice("elixir", 1, 10)
"lixir"

iex> String.slice("elixir", 10, 3)
""

如果開始位置為負數,它會根據字串長度正規化並限制為 0

iex> String.slice("elixir", -4, 4)
"ixir"

iex> String.slice("elixir", -10, 3)
"eli"

如果開始位置大於字串長度,則傳回一個空字串

iex> String.slice("elixir", 10, 1500)
""
@spec split(t()) :: [t()]

在每個 Unicode 空白出現處將字串分割為子字串,並忽略開頭和結尾的空白。空白群組視為單一出現。分割不會發生在不換行空白上。

範例

iex> String.split("foo bar")
["foo", "bar"]

iex> String.split("foo" <> <<194, 133>> <> "bar")
["foo", "bar"]

iex> String.split(" foo   bar ")
["foo", "bar"]

iex> String.split("no\u00a0break")
["no\u00a0break"]
連結到此函式

split(字串, 模式, 選項 \\ [])

檢視原始碼
@spec split(t(), pattern() | Regex.t(), keyword()) :: [t()]

根據模式將字串分割成數個部分。

傳回這些部分的清單。

pattern 可以是字串、字串清單、正規表示式或已編譯的模式。

預設情況下,字串會被切成盡可能多的部分,但可透過 :parts 選項控制。

只有當 :trim 選項設為 true 時,才會從結果中移除空字串。

當使用的樣式為正規表示式時,字串會使用 Regex.split/3 來切分。

選項

  • :parts(正整數或 :infinity) - 字串最多會被切成此選項指定的數量。如果為 :infinity,字串會被切成所有可能的部份。預設為 :infinity

  • :trim(布林值) - 如果為 true,會從結果清單中移除空字串。

如果 pattern 為正規表示式,此函式也會接受 Regex.split/3 接受的所有選項。

範例

使用字串樣式切分

iex> String.split("a,b,c", ",")
["a", "b", "c"]

iex> String.split("a,b,c", ",", parts: 2)
["a", "b,c"]

iex> String.split(" a b c ", " ", trim: true)
["a", "b", "c"]

樣式的清單

iex> String.split("1,2 3,4", [" ", ","])
["1", "2", "3", "4"]

正規表示式

iex> String.split("a,b,c", ~r{,})
["a", "b", "c"]

iex> String.split("a,b,c", ~r{,}, parts: 2)
["a", "b,c"]

iex> String.split(" a b c ", ~r{\s}, trim: true)
["a", "b", "c"]

iex> String.split("abc", ~r{b}, include_captures: true)
["a", "b", "c"]

已編譯的樣式

iex> pattern = :binary.compile_pattern([" ", ","])
iex> String.split("1,2 3,4", pattern)
["1", "2", "3", "4"]

在空字串上切分會傳回字位元

iex> String.split("abc", "")
["", "a", "b", "c", ""]

iex> String.split("abc", "", trim: true)
["a", "b", "c"]

iex> String.split("abc", "", parts: 1)
["abc"]

iex> String.split("abc", "", parts: 3)
["", "a", "bc"]

請注意,此函式可以在字位元界線內或跨界切分。例如,字位元「é」是由字元「e」和銳音符號組成。以下會將字串切成兩部分

iex> String.split(String.normalize("é", :nfd), "e")
["", "́"]

但是,如果「é」由單一字元「帶銳音符號的 e」表示,則它只會將字串切成一部分

iex> String.split(String.normalize("é", :nfc), "e")
["é"]
@spec split_at(t(), integer()) :: {t(), t()}

在指定偏移量處將字串分割為兩個部分。當給定的偏移量為負數時,位置會從字串結尾開始計算。

偏移量會限制在字串長度內。傳回包含兩個元素的元組。

注意:請記住此函式會在字位元上切分,因此它必須線性地遍歷字串。如果您想根據位元組數來切分字串或二進位,請改用 Kernel.binary_part/3

範例

iex> String.split_at("sweetelixir", 5)
{"sweet", "elixir"}

iex> String.split_at("sweetelixir", -6)
{"sweet", "elixir"}

iex> String.split_at("abc", 0)
{"", "abc"}

iex> String.split_at("abc", 1000)
{"abc", ""}

iex> String.split_at("abc", -1000)
{"", "abc"}
連結到此函式

splitter(字串, 模式, 選項 \\ [])

檢視原始碼
@spec splitter(t(), pattern(), keyword()) :: Enumerable.t()

傳回一個可列舉物件,依需求將字串分割。

這與 split/3 相反,後者會一次切分整個字串。

此函式在設計上不支援正規表示式。在使用正規表示式時,通常讓正規表示式一次遍歷整個字串會比像此函式一樣分批遍歷更有效率。

選項

  • :trim - 當 true 時,不會發出空模式

範例

iex> String.splitter("1,2 3,4 5,6 7,8,...,99999", [" ", ","]) |> Enum.take(4)
["1", "2", "3", "4"]

iex> String.splitter("abcd", "") |> Enum.take(10)
["", "a", "b", "c", "d", ""]

iex> String.splitter("abcd", "", trim: true) |> Enum.take(10)
["a", "b", "c", "d"]

也可以提供已編譯的模式

iex> pattern = :binary.compile_pattern([" ", ","])
iex> String.splitter("1,2 3,4 5,6 7,8,...,99999", pattern) |> Enum.take(4)
["1", "2", "3", "4"]
連結到此函式

starts_with?(字串, 前綴)

檢視原始碼
@spec starts_with?(t(), t() | [t()]) :: boolean()

如果 string 以任何給定的前綴開頭,則回傳 true

prefix 可以是字串、字串清單或已編譯的模式。

範例

iex> String.starts_with?("elixir", "eli")
true
iex> String.starts_with?("elixir", ["erlang", "elixir"])
true
iex> String.starts_with?("elixir", ["erlang", "ruby"])
false

空字串永遠會相符

iex> String.starts_with?("elixir", "")
true
iex> String.starts_with?("elixir", ["", "other"])
true

空清單永遠不會相符

iex> String.starts_with?("elixir", [])
false

iex> String.starts_with?("", [])
false
@spec to_atom(t()) :: atom()

將字串轉換為現有的原子或建立新的原子。

警告:此函式會動態建立原子,而原子不會被垃圾回收。因此,string 不應為不受信任的值,例如從 socket 或網路請求中接收的輸入。可以考慮改用 to_existing_atom/1

預設情況下,原子的最大數量為 1_048_576。可以使用 VM 選項 +t 提高或降低此限制。

原子的最大大小為 255 個 Unicode 碼點。

由編譯器內嵌。

範例

iex> String.to_atom("my_atom")
:my_atom
@spec to_charlist(t()) :: charlist()

將字串轉換為字元清單。

具體來說,此函式會取得 UTF-8 編碼的二進位資料,並傳回其整數碼點清單。它類似於 codepoints/1,但後者傳回的是字串形式的碼點清單。

如果您需要處理位元組,請參閱 :binary 模組

範例

iex> String.to_charlist("foo")
~c"foo"
@spec to_existing_atom(t()) :: atom()

將字串轉換為現有的原子,如果原子不存在,則會引發錯誤。

原子的最大大小為 255 個 Unicode 碼點。如果原子不存在,會引發 ArgumentError

由編譯器內嵌。

原子和模組

由於 Elixir 是一種編譯語言,因此在模組中定義的原子只有在載入該模組後才會存在,這通常發生在執行模組中的函式時。因此,通常建議只呼叫 String.to_existing_atom/1 來轉換在呼叫 to_existing_atom/1 的函式所屬模組中定義的原子。

若要從字串安全建立模組名稱本身,建議使用 Module.safe_concat/1

範例

iex> _ = :my_atom
iex> String.to_existing_atom("my_atom")
:my_atom
@spec to_float(t()) :: float()

回傳一個浮點數,其文字表示為 string

字串 必須是包含小數點的浮點數字串表示。若要將不含小數點的字串解析為浮點數,則應使用 Float.parse/1。否則,將會引發 ArgumentError

由編譯器內嵌。

範例

iex> String.to_float("2.2017764e+0")
2.2017764

iex> String.to_float("3.0")
3.0

String.to_float("3")
** (ArgumentError) argument error
@spec to_integer(t()) :: integer()

回傳一個整數,其文字表示為 string

字串 必須是整數的字串表示。否則,將會引發 ArgumentError。若要解析可能包含格式錯誤整數的字串,請使用 Integer.parse/1

由編譯器內嵌。

範例

iex> String.to_integer("123")
123

傳遞不代表整數的字串會導致錯誤

String.to_integer("invalid data")
** (ArgumentError) argument error
@spec to_integer(t(), 2..36) :: integer()

回傳一個整數,其文字表示為 string,底數為 base

由編譯器內嵌。

範例

iex> String.to_integer("3FF", 16)
1023
@spec trim(t()) :: t()

回傳一個字串,其中已移除所有前導和尾隨的 Unicode 空白。

範例

iex> String.trim("\n  abc\n  ")
"abc"
@spec trim(t(), t()) :: t()

回傳一個字串,其中已移除所有前導和尾隨的 to_trim 字元。

範例

iex> String.trim("a  abc  a", "a")
"  abc  "
@spec trim_leading(t()) :: t()

回傳一個字串,其中已移除所有前導的 Unicode 空白。

範例

iex> String.trim_leading("\n  abc   ")
"abc   "
連結到此函式

trim_leading(string, to_trim)

檢視原始碼
@spec trim_leading(t(), t()) :: t()

回傳一個字串,其中已移除所有前導的 to_trim 字元。

範例

iex> String.trim_leading("__ abc _", "_")
" abc _"

iex> String.trim_leading("1 abc", "11")
"1 abc"
@spec trim_trailing(t()) :: t()

回傳一個字串,其中已移除所有尾隨的 Unicode 空白。

範例

iex> String.trim_trailing("   abc\n  ")
"   abc"
連結到此函式

trim_trailing(string, to_trim)

檢視原始碼
@spec trim_trailing(t(), t()) :: t()

回傳一個字串,其中已移除所有尾隨的 to_trim 字元。

範例

iex> String.trim_trailing("_ abc __", "_")
"_ abc "

iex> String.trim_trailing("abc 1", "11")
"abc 1"
連結到此函式

upcase(string, mode \\ :default)

檢視原始碼
@spec upcase(t(), :default | :ascii | :greek | :turkic) :: t()

根據 mode 將給定字串中的所有字元轉換為大寫。

模式 可能為 :default:ascii:greek:turkic:default 模式會考量 Unicode 標準中概述的所有非條件轉換。 :ascii 僅將 a 到 z 的字母轉換為大寫。 :greek 包含希臘文中發現的內容敏感對應。 :turkic 適當地處理帶有非點變體的字母 i。

範例

iex> String.upcase("abcd")
"ABCD"

iex> String.upcase("ab 123 xpto")
"AB 123 XPTO"

iex> String.upcase("olá")
"OLÁ"

:ascii 模式會忽略 Unicode 字元,並在您知道字串僅包含 ASCII 字元時提供效能更高的實作

iex> String.upcase("olá", :ascii)
"OLá"

:turkic 會正確處理帶有非點變體的字母 i

iex> String.upcase("ıi")
"II"

iex> String.upcase("ıi", :turkic)
"Iİ"

另請參閱 downcase/2capitalize/2 以取得其他轉換。

連結到此函式

valid?(string, algorithm \\ :default)

檢視原始碼

檢查 string 是否只包含有效字元。

演算法可以是 :default:fast_ascii。從驗證角度來看,這兩種演算法是等效的(它們永遠會產生相同的輸出),但 :fast_ascii 在特定場景中可以產生顯著的效能提升。

如果符合下列所有條件,您可能想要嘗試 :fast_ascii 演算法,看看它是否能在您的特定場景中產生效能提升

  • 您在 64 位元平台上執行 Erlang/OTP 26 或更新版本
  • 您預期大部分字串長度會超過 ~64 位元組
  • 您預期大部分字串主要包含 ASCII 碼點

請注意,:fast_ascii 演算法不會影響正確性,您可以預期 String.valid?/2 的輸出與演算法無關。唯一預期的差異是效能,與 :default 演算法相比,預期會隨著字串長度大致線性提升。

範例

iex> String.valid?("a")
true

iex> String.valid?("ø")
true

iex> String.valid?(<<0xFFFF::16>>)
false

iex> String.valid?(<<0xEF, 0xB7, 0x90>>)
true

iex> String.valid?("asd" <> <<0xFFFF::16>>)
false

iex> String.valid?("a", :fast_ascii)
true

iex> String.valid?(4)
** (FunctionClauseError) no function clause matching in String.valid?/2