字符

字符串 属于 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

子字符串

可以使用切片表示法来提取子字符串。语法是 .[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 个练习即可练习 字符串