字串

字串 在 jq

6 個練習

關於 字串

回想一下,jq支援和 JSON 相同的資料型態。 JSON 把字串描述為:

字串是由零個或多個 Unicode 字元組成的序列,以雙引號包住,並使用反斜線跳脫。

跳脫序列

在字串中,使用反斜線字元來嵌入「特殊」字元:

  • \" 字面上的雙引號,
  • \\ 字面上的反斜線,
  • 空白字元 \n、\t、\r、\f、\b
  • Unicode 字元 \uAAAA,其中 A 是十六進位數字

字串長度

想知道字元的數量,可以使用length函式。

$ jq -cn --args  '$ARGS.positional[] | length' "Hello world!" "❄🌡🤧🤒🏥🕰😀"
12
7

想知道實際的_位元組_數量,可以使用utf8bytelength函式。

$ jq -cn --args  '$ARGS.positional[] | utf8bytelength' "Hello world!" "❄🌡🤧🤒🏥🕰😀"
12
27

子字串

可以使用 slice 標記法來取出子字串。 語法是.[i:j]。 回傳的子字串長度為j - i,內容是從索引i(含)到索引j(不含)的字元。 任一個索引都可以是負數,此時會從字串尾端往回數。 任一個索引也可以省略,此時代表字串的開頭或結尾。 索引從 0 開始。

"abcdefghij"[3:6]   # => "def"
"abcdefghij"[3:]    # => "defghij"
"abcdefghij"[:-2]   # => "abcdefgh"

串接

使用+來連接字串:

"Hello" + " " + "world!"
# => "Hello world!"

當拿到的是字串陣列時,使用add:

["Hello", " ", "world!"] | add
# => "Hello world!"

分割與合併

分割可以使用split/1函式或/運算子:

"Hello beautiful world!" | split(" ")   # => ["Hello", "beautiful", "world!"]
"Hello beautiful world!" / " "          # => ["Hello", "beautiful", "world!"]

split/1的反向操作是join/1。

我們經常需要把字串轉成字元陣列。 有兩種做法:

  1. 用空字串分割

    "Hi friend 😀" / ""   # => ["H","i"," ","f","r","i","e","n","d"," ","😀"]
    
  2. 用explode拆成_碼點_陣列

    "Hi friend 😀" | explode   # => [72,105,32,102,114,105,101,110,100,32,128512]
    

    implode是explode的反向操作。

找出子字串的索引

使用index/1函式;索引從 0 開始。

"hello" | index("el")'   # => 1

如果字串裡沒有這個子字串,結果會是null

"hello" | index("elk")   # => null

其他實用的函式還有rindex/1和indices。

字串內插

在字串中,\(expression)這個序列會把該運算式的_結果_嵌入字串:

"The current datetime is \(now | strflocaltime("%c"))"   # => "The current datetime is Wed Nov 16 17:06:33 2022"

大小寫轉換

使用ascii_downcase和ascii_upcase函式來改變字串的大小寫。

把字串轉成數字

使用tonumber函式從字串建立數字。

如果字串無法轉成數字,就會拋出錯誤,因此可能需要用到try-catch。

$ jq -cn --args '$ARGS.positional[] | [., tonumber]' 42 3.14 oops 1e6 0xbeef
["42",42]
["3.14",3.14]
jq: error (at <unknown>): Invalid numeric literal at EOF at line 1, column 4 (while parsing 'oops')

$ echo $?
5

$ jq -cn --args '$ARGS.positional[] | try [., tonumber] catch "not a number"' 42 3.14 oops 1e6 0xbeef
["42",42]
["3.14",3.14]
"not a number"
["1e6",1000000]
"not a number"

請注意,JSON 數字並不包含某些語言支援的十六進位或八進位變化。

其他函式

這些函式的詳細資訊請查閱手冊:

  • 重複字串:*
  • 測試是否包含:contains/1、inside/1、indices/1、index/1、rindex/1、startswith/1、endswith/1
  • 修剪:lsrimstr/1、rtrimstr/1
  • 格式化函式:@text、@json、@html、@uri、@csv、@tsv、@sh、@base64、@base64d

正規表示式

jq對正規表示式有豐富的支援:這會是之後某一單元的主題。

透過 GitHub 編輯 連結會在新視窗或分頁中開啟

學習 字串

練習已鎖定

再解鎖 8 個練習,就能練習 字串