Presto | 字符串运算符和函数
字符串运算符
||
运算符,字符串连接运算符,将运算符左右两边的字符串进行连接,作用同函数 concat(string1, ..., stringN)
。
示例
1 | select 'Here I am, ' || 'here I am How do you do?' |
输出
1 | Here I am, here I am How do you do? |
字符串函数
需要注意的是,以下这些函数假设输入的字符串所包含的都是有效的 UTF-8 编码的 Unicode 码点。函数并没有对 UTF-8 的有效性进行明确的检查。如果输入了无效的 UTF-8,这些函数可能会返回错误的结果。无效的 UTF-8 数据可以使用 from_utf8()
函数进行修正。
此外,这些函数操作的都是 Unicode 码点,而不是用户可见的字符或字母。某些语言会将多个码点组合成单个用户感知的字符,即一种语言书写系统的基本单位。但这些函数会将每个码点视为独立的单位。
lower()
和 upper()
函数无法执行立陶宛语、土耳其语和阿塞拜疆语等某些语言所需的区域敏感、上下文敏感或一对多的映射。具体来说,对这些语言,lower()
和 upper()
函数会返回不正确的结果。
Unicode 码点(code point)是指 Unicode 字符编码方案中的每个独立的字符,是构成 Unicode 字符串的基本单位。它代表 Unicode 为每个字符指定的整数值,用来在计算机内唯一地表示这个字符。
举例来说:
- A 的 Unicode 码点是 U+0041,即十六进制的 0041,相当于十进制的 65
- 中 的 Unicode 码点是 U+4E2D,即十六进制的 4E2D,相当于十进制的 20013
- 𠮷 的 Unicode 码点是 U+20BB7,即十六进制的 20BB7,相当于十进制的 134071
通过 Unicode 码点,计算机可以准确地理解和处理所有世界各地的文字,包括表意文字如中文汉字,表音文字如拉丁字母,以及其它各种书写系统的文字。事实上,绝大多数的世界文字都已经由 Unicode 标准所覆盖。
Uniocde 标准定义了一个码位空间,覆盖了绝大多数的字体和符号。这使得以数字形式准确表达世界上的各种语言成为可能。Unicode 码点实际上已成为在数字世界里表示文字的基石。
简单来说,Unicode 码点就是 Unicode 给每个字符指定的数字 ID。它是计算机内表示文字的基本单元,通过这些码点,计算机可以精确地处理各种语言的文字。
chr(n) → varchar
返回 Unicode 码点 n
对应的字符,n
为整数。
示例
下面的示例演示了如何使用 chr(n)
函数返回对应 Unicode 码点的字符。
1 | select chr(65) |
此示例输出结果为 A。
codepoint(string) → integer
返回对应字符的 Unicode 码点。
示例
下面的示例演示了如何使用 codepoint(string)
函数返回对应字符的 Unicode 码点。
1 | select codepoint('A') |
此示例输出结果为 65。
concat(string1, …, stringN) → varchar
返回 string1
, ...
, stringN
连接后的值。这个函数提供的功能与 SQL 标准的连接操作符(||
)相同。
示例
下面的示例演示了如何使用 concat(string1, ..., stringN)
函数连接两个字符串。
1 | select concat('Mommy Finger, ', 'Mommy Finger, ', 'where are you?') |
此示例输出结果为 Mommy Finger, Mommy Finger, where are you? 。
注意:该方法直接连接 string1
、...
、stringN
,不会添加任何分隔符。
hamming_distance(string1, string2) → bigint
返回 string1
和 string2
的汉明距离,即两个字符串相应字符不同位置的数目。注意,这两个字符串必须具有相同的长度。
示例
下面的示例演示了如何使用 hamming_distance(string1, string2)
函数计算字符串 1011101
与 1001001
之间的汉明距离。
1 | select hamming_distance('1011101', '1001001') |
此示例输出结果为 2。
在信息论中,两个等长字符串之间的汉明距离(英语:Hamming distance)是两个字符串对应位置的不同字符的个数。换句话说,它就是将一个字符串变换成另外一个字符串所需要替换的字符个数。例如:
1011101 与 1001001 之间的汉明距离是 2。
2143896 与2233796 之间的汉明距离是 3。
“toned” 与 “roses” 之间的汉明距离是 3。
摘自:https://zh.wikipedia.org/wiki/汉明距离
length(string) → bigint
返回字符串的长度(以字符为单位)。
示例
下面的示例演示了如何使用 length(string)
函数计算字符串 和A2*
的字符数。
1 | select length('和A2*') |
此示例输出结果为 4。
levenshtein_distance(string1, string2) → bigint
返回 string1
和 string2
的莱文斯坦编辑距离,即将 string1
变为 string2
所需的最小单字符编辑次数(插入、删除或替换)。
示例
下面的示例演示了如何使用 levenshtein_distance(string1, string2)
函数计算字符串 Daddy Finger
与 Mommy Finger, where are you?
之间的莱文斯坦编辑距离。
1 | select levenshtein_distance('Daddy Finger', 'Mommy Finger, where are you?') |
输出结果为 20。
lower(string) → varchar
将字符串转换为小写。
示例
下面的例子将一个混合大小写的字符串转换为小写。
1 | select lower('Daddy Finger, Daddy Finger, where are you?') |
输出结果为 daddy finger, daddy finger, where are you?。
upper(string) → varchar
将字符串转换为大写。
示例
下面的例子将一个混合大小写的字符串转换为大写。
1 | select upper('Daddy Finger, Daddy Finger, where are you?') |
输出结果为 DADDY FINGER, DADDY FINGER, WHERE ARE YOU?。
lpad(string, size, padstring) → varchar
返回一个新字符串,该字符串通过在 string
左侧填充 padstring
来达到指定的总长度 size
,实现右对齐。如果 size
小于字符串的长度,结果将被截断为 size
个字符。size
不能为负数,padstring
必须为非空。
参数
string
需要填充的字符串
size
填充后的字符串长度
padstring
用来填充的字符串
示例
下面的例子演示了如何使用 lpad(string, size, padstring)
填充字符串。
1 | select lpad('M', 5, 'Z'), lpad('M', 5, 'ZYX'), lpad('ABC', 2, '$') |
输出结果为 ZZZZM,ZYXZM,AB。
rpad(string, size, padstring) → varchar
返回一个新字符串,该字符串通过在 string
右侧填充 padstring
来达到指定的总长度 size
,实现左对齐。如果 size
小于字符串的长度,结果将被截断为 size
个字符。size
不能为负数,padstring
必须为非空。
参数
string
需要填充的字符串
size
结果字符串中的字符数
padstring
用来填充的字符串
示例
下面的例子演示了如何使用 rpad(string, size, padstring)
填充字符串。
1 | select rpad('M', 5, 'Z'), rpad('M', 5, 'ZYX'), rpad('ABC', 2, '$') |
输出结果为 MZZZZ,MZYXZ,AB。
trim(string) → varchar
删除字符串 string
开头和末尾的空白字符。如果字符串无可删除的空白字符,则返回原字符串。
示例
下面的例子演示了如何使用 trim(string)
函数删除字符串开头和末尾的所有空白字符。
1 | select trim(' $$ $$ ') |
输出结果为 $$$ $$$。
ltrim(string) → varchar
删除字符串中的所有前导空白字符。
此方法返回删除字符串开头所有可删除的空白字符后的字符串。如果字符串无空白字符可删除,则返回原字符串。
示例
以下示例演示了 ltrim(string)
方法的基本功能。
1 | select ltrim(' $$ $$ '), ltrim('$A') |
输出结果为 $$$ $$$ ,$A
。
rtrim(string) → varchar
删除字符串 string
末尾的所有空白字符。
此方法返回删除字符串末尾所有可删除的空白字符后的字符串。如果字符串无空白字符可删除,则返回原字符串。
示例
以下示例演示了 rtrim(string)
方法的基本功能。
1 | select rtrim(' $$ $$ '), rtrim('$A') |
输出结果为 $$$ $$$,$A
。
replace(string, search) → varchar
此方法删除字符串(string
)中出现的所有指定的字符串(search
)。
示例
下面的例子演示了如何使用 replace(string, search)
从字符串中删除指定字符。
1 | select replace('Daddy Finger, Daddy Finger, where are you?', 'Daddy Finger, ') |
输出结果为 where are you?
。
replace(string, search, replace) → varchar
该函数使用 replace
替换字符串(string
)中出现的所有指定字符串(search
)。如果在字符串中找不到 search
,则返回原字符串。
参数
string
原字符串
search
要替换的字符串。
replace
要替换出现的所有 search
的字符串。
示例
以下示例通过用连接符(-)代替一系列数字之间的逗号。
1 | select replace('1,2,3,4,5,6,7,8,9', ',', '-') |
输出结果为 1-2-3-4-5-6-7-8-9。
如果在字符串中找不到 search
,则返回原字符串。如:
1 | select replace('1,2,3', 'a', '$') |
输出结果为 1,2,3。
如果 search
为空字符串,在 string
的每个字符前面和结尾插入 replace
。如:
1 | select replace('1,2,3', '', '$$') |
输出结果为 ,,。
reverse(string) → varchar
返回字符串 string
的字符顺序反转后的字符串。
示例
1 | select reverse('123456789') |
输出结果为 987654321。
split(string, delimiter)
根据 delimiter
对字符串 string
进行分割,并返回字符串数组。
示例
1 | select split('1,2,3', ','), split('1,2,', ','), split('1,,2,3', ',,') |
输出结果为 [‘1’,’2’,’3’],[‘1’,’2’,’’],[‘1’,’2,3’]。
split(string, delimiter, limit)
根据分隔符 delimiter
对字符串 string
进行分割,并返回一个数组,数组大小不超过限定值 limit
。数组中的最后一个元素总包含字符串 string
中剩余的所有内容。限定值 limit
必须是正整数。
示例
1 | select split('1$$2$$3$$4$$5', '$$'), split('1$$2$$3$$4$$5', '$$', 3) |
输出结果为 [‘1’,’2’,’3’,’4’,’5’],[‘1’,’2’,’35’]。
split_part(string, delimiter, index) → varchar
根据分隔符 delimiter
对字符串 string
进行分割,并返回第 index
个字段。字段索引从 1
开始计数。如果索引值超过字段总数,则返回 null。
示例
1 | select split('a,b,c,d,e', ','), split_part('a,b,c,d,e', ',', 3) |
输出结果为 [‘a’,’b’,’c’,’d’,’e’],c。
split_to_map(string, entryDelimiter, keyValueDelimiter) → map
根据 entryDelimiter
和 keyValueDelimiter
这两个分隔符对字符串 string
进行层层分割,并返回一个映射(Map)。entryDelimiter
将字符串 string
划分为多个键值对。keyValueDelimiter
进一步将每对键值对划分为键和对应的值。
请注意,entryDelimiter
和 keyValueDelimiter
被按原义解释,即作为完整的字符串匹配。
示例
1 | select split_to_map('a:1;b:2;c:3', ';', ':') |
输出结果为 {a=1, b=2, c=3}。
如果在转换成映射的过程中,出现 key 相同的情况则会抛出异常:
1 | select split_to_map('a:1;b:2;b:3', ';', ':') |
异常信息如下:
SQL 错误 [7]: Query failed (#20230509_102207_03215_xs34i): Duplicate keys (b) are not allowed. Specifying a lambda to resolve conflicts can avoid this error
split_to_map(string, entryDelimiter, keyValueDelimiter, function(K, V1, V2, R)) → map
功能同 split_to_map(string, entryDelimiter, keyValueDelimiter)
,只是在键重复的情况下,会调用 function(K,V1,V2,R)
来确定映射中应该使用的值。
示例
1 | select split_to_map('a:1;b:2;a:3', ';', ':', (k, v1, v2) -> v1) |
输出结果为 {a=1, b=2}。
1 | select split_to_map('a:1;b:2;a:3', ';', ':', (k, v1, v2) -> v2) |
输出结果为 {a=3, b=2}。
1 | select split_to_map('a:1;b:2;a:3', ';', ':', (k, v1, v2) -> concat(v1, v2)) |
输出结果为 **{a=13, b=2}。
split_to_multimap(string, entryDelimiter, keyValueDelimiter)
根据 entryDelimiter
和 keyValueDelimiter
这两个分隔符对字符串 string
进行层层分割,并返回一个映射(Map),其中每个唯一键对应一个值数组。entryDelimiter
将字符串 string
划分为多个键值对。keyValueDelimiter
进一步将每对键值对划分为键和对应的值。
每个键所对应的值数组内的值的顺序与这些值在字符串 string
中出现的顺序相同。
请注意,entryDelimiter
和 keyValueDelimiter
被按原义解释,即作为完整的字符串匹配。
示例
1 | select split_to_multimap('a:1;b:2;b:3', ';', ':') |
输出结果为 {a=[1], b=[2, 3]}。
strpos(string, substring) → bigint
返回字符串 string
中子字符串 substring
第一次出现的起始位置索引。位置索引从 1 开始计数。如果未找到子字符串 substring
,则返回 0。
示例
1 | select strpos('Mommy Finger, Mommy Finger, where are you?', 'Mommy Finger') |
输出结果为 1。
strpos(string, substring, instance) → bigint
返回字符串 string
中子字符串 substring
第 instance
个出现位置的索引。instance
必须是正整数。位置索引从 1 开始计数。如果未找到子字符串 substring
的第 instance
个出现位置,则返回 0。
示例
1 | select strpos('Mommy Finger, Mommy Finger, where are you?', 'Mommy Finger', 2) |
输出结果为 15。
strrpos(string, substring) → bigint
返回字符串 string
中子字符串 substring
最后一次出现的起始位置索引。位置索引从 1 开始计数。如果未找到子字符串 substring
,则返回 0。
示例
1 | select strrpos('Mommy Finger, Mommy Finger, where are you?', 'Mommy Finger') |
输出结果为 15。
strrpos(string, substring, instance) → bigint
从字符串 string
的末尾开始,返回子字符串 substring
第 instance
个出现位置的索引。instance
必须是正整数。位置索引从 1 开始计数。如果未找到子字符串 substring
的第 instance
个出现位置,则返回 0。
示例
1 | select strrpos('Mommy Finger, Mommy Finger, where are you?', 'Mommy Finger', 2) |
输出结果为 1。
position(substring IN string) → bigint
返回字符串 string
中子字符串 substring
第一次出现的起始位置索引。位置索引从 1 开始计数。如果未找到子字符串 substring
,则返回 0。
示例
1 | select position('Mommy Finger' in 'Mommy Finger, Mommy Finger, where are you?') |
输出结果为 1。
substr(string, start) → varchar
从起始位置索引 start
开始返回字符串 string
的其余部分。位置索引从 1 开始计数。负的起始位置索引被看作相对于字符串末尾的位置。
示例
1 | select substr('Mommy Finger', 7) |
输出结果为 Finger
。
substr(string, start, length) → varchar
从起始位置索引 start
开始,返回字符串 string
长度为 length
的子字符串。位置索引从 1 开始计数。负的起始位置索引被看作相对于字符串末尾的位置。
示例
1 | select substr('Mommy Finger', 7, 2) |
输出结果为 Fi
。
word_stem(word) → varchar
返回英语词汇 word
的词干。
返回英语单词 word
的词根(词干)。
word_stem(word, lang) → varchar
返回语言为 lang
的词汇 word
的词干。
返回语言 lang 的单词 word 的词根(词干)。
Unicode 函数
normalize(string) → varchar
使用 Unicode 标准化形式 NFC(规范等价合成)转换字符串 string
。
normalize(string, form) → varchar
使用指定的正规化形式转换字符串 string
。form
必须是以下关键字之一:
- NFC:根据“规范等价变换表”将压缩变换作为其正规化形式之一使用的字符序列转换为其规范变换。
- NFD:通过在其正规化形式中解构变换基本汉字将字符序列分解为组成基本汉字的分解序列。
- NFKC:非正规化形式通过省略等价变换使字符序列更流畅地显示和排序。
- NFKD:非规范等价键序列通过在其非规范形式中解构变换基本汉字将字符序列分解为组成基本汉字的分解序列,并使其更规范。
如果指定的形式无效,则抛出异常。
示例
1 | select normalize('中国', NFKD) |
注意,该 SQL 标准函数具有特殊语法,需要将 form
指定为关键字,而不是字符串。如以下写法将抛出异常:
1 | select normalize('中国', 'NFKD') |
异常信息如下:
SQL 错误 [1]: Query failed (#20230509_121235_03637_xs34i): line 1:24: mismatched input ‘’NFKD’’. Expecting: ‘NFC’, ‘NFD’, ‘NFKC’, ‘NFKD’
to_utf8(string) → varbinary
将字符串 string
编码为 UTF-8 二进制表示。
示例
1 | select to_utf8('How are you, today,你今天怎么样') |
输出结果如下(二进制显示为乱码):
1 | How are you, todayï¼ ä½ ä» å¤©æ ä¹ æ · |
from_utf8(binary) → varchar
解码 UTF-8 编码的二进制数据 binary
。无效的 UTF-8 序列将被 Unicode 替代字符 U+FFFD
替换。
示例
1 | select from_utf8(to_utf8('How are you, today,你今天怎么样')) |
输出结果如下:
1 | How are you, today,你今天怎么样 |
from_utf8(binary, replace) → varchar
解码 UTF-8 编码的二进制数据 binary
。无效的 UTF-8 序列将被替换字符串 replace
替换。替换字符串 replace
必须是一个单字符字符串或空字符串(在这种情况下,无效字符将被删除)。
key_sampling_percent(varchar) → double
根据给定的 varchar
的哈希值生成 0.0 到 1.0 之间的双精度浮点数。此函数用于确定性数据抽样。
(END)