
# 字符串函数
#### 字符串函数
数据湖探索（DLI）提供了丰富的字符串函数，用于处理和转换字符串数据。这些函数包括拼接、大小写转换、截取子串、替换、正则匹配、编码解码、格式转换等。此外，还支持字符串长度计算、位置查找、填充、反转等功能，以及从JSON字符串中提取值的JSON_VAL函数。这些功能广泛应用于数据清洗、文本处理和数据分析场景，为开发者提供强大的工具支持。
字符串函数简介请参考[表1]，更多内容参考[Apache Flink](https://nightlies.apache.org/flink)。
 表1字符串函数 
| 函数                                                                         | 返回类型    | 描述                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
|:---|:---|:---|
| string1 \|\| string2                                                       | STRING  | 返回两个字符串的拼接                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| CHAR_LENGTH(string) CHARACTER_LENGTH(string) | INT     | 返回字符串中的字符数量                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| UPPER(string)                                                              | STRING  | 返回字符串的大写形式                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| LOWER(string)                                                              | STRING  | 返回字符串的小写形式                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| POSITION(string1 IN string2)                                               | INT     | 返回第一个字符串在第二个字符串中首次出现的位置。若第一个字符串不存在与第二个字符串，则返回0                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| TRIM(\[ BOTH \| LEADING \| TRAILING \] string1 FROM string2)               | STRING  | 去除string2字符串的首尾(或首部、或尾部)的string1字符串                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| LTRIM(string)                                                              | STRING  | 返回去除首部空格后的字符串 例如LTRIM(' This is a test String.') 返回"This is a test String."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| RTRIM(string)                                                              | STRING  | 返回去除尾部空格后的字符串 例如RTRIM('This is a test String. ') 返回"This is a test String."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| REPEAT(string, integer)                                                    | STRING  | 返回integer个string连接后的字符串 例如REPEAT('This is a test String.', 2) 返回"This is a test String.This is a test String."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| REGEXP_REPLACE(string1, string2, string3)                                  | STRING  | 用string3代替string1中的符合正则表达式string2的字符串，并返回替换后的string1字符串 例如REGEXP_REPLACE('foobar', 'oo\|ar', '') 返回"fb" REGEXP_REPLACE('ab\\ab', '\\\\', 'e')返回"abeab"                                                                                                                                                                                                                                                                                                                                                                                                               |
| OVERLAY(string1 PLACING string2 FROM integer1 \[ FOR integer2 \])          | STRING  | 用string2代替string1中的字符串，从integer1开始，替换长度为integer2，并返回替换后的string1字符串 integer2默认为string2的长度 例如OVERLAY('This is an old string' PLACING ' new' FROM 10 FOR 5)返回"This is a new string"                                                                                                                                                                                                                                                                                                                                                                                  |
| SUBSTRING(string FROM integer1 \[ FOR integer2 \])                         | STRING  | 返回string中从integer1位置开始的长度为integer2的子字符串。若integer2未配置，则默认返回从integer1开始到末尾的子字符串                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| REPLACE(string1, string2, string3)                                         | STRING  | 用string3代替string1中的string2后的字符串，并返回替换后的string1字符串 例如：REPLACE('hello world', 'world', 'flink') 返回"hello flink" REPLACE('ababab', 'abab', 'z') 返回"zab" REPLACE('ab\\\\ab', '\\\\', 'e')返回"abeab"                                                                                                                                                                                                                                                                                                                                                                   |
| REGEXP_EXTRACT(string1, string2\[, integer\])                              | STRING  | 使用正则表达式string2匹配抽取字符串string1中的第integer个字串，integer从1开始，正则匹配提取。 若参数为 NULL或者正则不合法，则返回NULL。 例如REGEXP_EXTRACT('foothebar', 'foo(.\*?)(bar)', 2)" 返回"bar"                                                                                                                                                                                                                                                                                                                                                                                                                |
| INITCAP(string)                                                            | STRING  | 返回将字符串的首字符大写其余字符转为小写后的字符串                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| CONCAT(string1, string2,...)                                               | STRING  | 返回将两个或多个字符串拼接后的新字符串。 例如 CONCAT('AA', 'BB', 'CC') 返回"AABBCC"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| CONCAT_WS(string1, string2, string3,...)                                   | STRING  | 返回将每个参数和第一个参数指定的分隔符依次连接到一起组成的字符串。若string1是null，则返回null。若其他参数为null，在执行拼接过程中跳过取值为null的参数 例如CONCAT_WS('\~', 'AA', NULL, 'BB', '', 'CC') 返回"AA\~BB\~\~CC"                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| LPAD(string1, integer, string2)                                            | STRING  | 将string2字符串拼接到string1字符串的左端，直到新的字符串达到指定长度integer为止 任意参数为null时，返回null 若integer为负数，则返回null 若integer不大于string1的长度，则返回string1裁剪为integer长度的字符串 例如LPAD('hi',4,'??') 返回"??hi" LPAD('hi',1,'??') 返回"h"                                                                                                                                                                                                                                                                           |
| RPAD(string1, integer, string2)                                            | STRING  | 将string2字符串拼接到string1字符串的右端，直到新的字符串达到指定长度integer为止 任意参数为null时，返回null 若integer为负数，则返回null 若integer不大于string1的长度，则返回string1裁剪为integer长度的字符串 例如RPAD('hi',4,'??') 返回 "hi??" RPAD('hi',1,'??') 返回"h"                                                                                                                                                                                                                                                                         |
| FROM_BASE64(string)                                                        | STRING  | 将base64编码的字符串str解析成对应字符串 若字符串为null，则返回null 例如FROM_BASE64('aGVsbG8gd29ybGQ=') 返回"hello world"                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| TO_BASE64(string)                                                          | STRING  | 将字符串基于base64编码 若字符串为null，则返回null 例如TO_BASE64('hello world') 返回"aGVsbG8gd29ybGQ="                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| ASCII(string)                                                              | INT     | 返回字符串的第一个字符的ASCII值 若字符串为null，则返回null 例如ascii('abc') 返回97 ascii(CAST(NULL AS VARCHAR)) 返回NULL                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| CHR(integer)                                                               | STRING  | 将ASCII码转换为字符 若integer大于255，则计算出integer除以255的余数，并将余数作为ASCII码值 若integer为null，则返回null chr(97) 返回a chr(353) 返回a                                                                                                                                                                                                                                                                                                                                                                                           |
| DECODE(binary, string)                                                     | STRING  | 使用提供的字符集string解码参数binary，字符集可以为'US-ASCII', 'ISO-8859-1', 'UTF-8', 'UTF-16BE', 'UTF-16LE', 'UTF-16' 若任意参数为null，则返回null                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| ENCODE(strinh1, string2)                                                   | STRING  | 使用提供的字符集string2编码字符串string1，字符集可以为'US-ASCII', 'ISO-8859-1', 'UTF-8', 'UTF-16BE', 'UTF-16LE', 'UTF-16' 若任意参数为null，则返回null                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| INSTR(string1, string2)                                                    | INT     | 返回string2在string1中首次出现的位置 若有参数为null，则返回null                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| LEFT(string, integer)                                                      | STRING  | 返回最左边的integer个字符 若integer为负数，则返回空 若存在参数为null，则返回null                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| RIGHT(string, integer)                                                     | STRING  | 返回最右侧的integer个字符 若integer为负数，则返回空 若存在参数为null，则返回null                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| LOCATE(string1, string2\[, integer\])                                      | INT     | 返回string1在string2的位置integer之后首次出现的位置 若string1在string2的位置integer之后不存在，则返回0 若integer不存在，则默认为0 若存在参数为null，则返回null                                                                                                                                                                                                                                                                                                                                                                                                                        |
| PARSE_URL(string1, string2\[, string3\])                                   | STRING  | 返回URL string1中指定的部分解析后的值 string2为'HOST'、'PATH'、'QUERY'、'REF'、'PROTOCOL'、'AUTHORITY'、'FILE'或'USERINFO' 若存在参数为null，则返回null 若string2为QUERY，也可以指定QUERY中的key为string3 例如： parse_url('http://facebook.com/path1/p.php?k1=v1\&k2=v2#Ref1', 'HOST')返回 'facebook.com' parse_url('http://facebook.com/path1/p.php?k1=v1\&k2=v2#Ref1', 'QUERY', 'k1') 返回'v1'                                                                                                |
| REGEXP(string1, string2)                                                   | BOOLEAN | 对指定的字符串执行一个正则表达式搜索，并返回一个BOOLEAN值表示是否找到指定的匹配模式。若找到，则返回TRUE。其中string1表示指定的字符串，string2表示正则表达式 若存在参数为null，则返回null                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| REVERSE(string)                                                            | STRING  | 反转字符串，返回字符串值的相反顺序。 若存在参数为null，则返回null 说明： 使用时请注意需在函数上加反引号 \` REVERSE \` 。                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| SPLIT_INDEX(string1, string2, integer1)                                    | STRING  | 以string2作为分隔符，将字符串string1分割成若干段，取其中的第integer1段。integer1从0开始 若integer1为负数，则返回null 如果任一参数为null，则返回null 具体函数说明请参考[SPLIT_INDEX 函数说明]。                                                                                                                                                                                                                                                                                                                                                                |
| STR_TO_MAP(string1\[, string2, string3\]\])                                | MAP     | 使用string2分隔符将string1分割成K-V对，并使用string3分隔每个K-V对，组装成MAP返回 string2默认为',' string3默认为'='                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| SUBSTR(string\[, integer1\[, integer2\]\])                                 | STRING  | 截取从位置integer1开始，长度为integer2的子串，并返回 若为指定integer2，翻截取到字符串结尾                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| JSON_VAL(STRING json_string, STRING json_path)                             | STRING  | 从json形式的字符串json_string中提取指定json_path的值。具体函数使用可以参考[JSON_VAL函数说明]说明。 说明： 以下规则优先级按照顺序从高到低。 1. 不允许json_string和json_path为NULL  2. json_string格式必须为合法的json串，否则函数返回NULL  3. json_string为空字符串，则函数返回空字符串  4. json_path为空字串或路径不存在，则函数返回NULL   |
   
 #### SPLIT_INDEX 函数说明
SPLIT_INDEX(string1, string2, integer1)
- **参数说明**
  - **string1：**
    - 类型：STRING
    
    - 说明：需要被分割的原始字符串。
    
    - 示例：'a,b,c,d' 或 'a\\bc\\bd'
     
  
  - **string2：**
    - 类型：STRING
    
    - 说明：分割字符串的分隔符。
    
    - 特殊字符处理：
      - 如果分隔符中包含特殊字符（如 \\\\、\* 等），需要使用双反斜杠 \\\\ 进行转义。
      
      - 分隔符为 . 时不需要转义。
      
      - 如果分隔符为 \\\\ 本身，应写为 '\\\\\\\\'。
       
     
  
  - **integer1：**
    - 类型：INT
    
    - 说明：指定提取的分割后的部分索引，从 0 开始计数。
    
    - 示例：0 表示提取第一个部分，1 表示提取第二个部分，依此类推。
     
   
- **返回值**
  返回分割后的字符串中指定索引位置的部分。
  如果索引超出范围或输入参数为 NULL，返回 NULL。
  
- **示例** 1
  SELECT SPLIT_INDEX('a,b,c,d', ',', 1); -- 返回 'b'
  
- **示例2：**
  点号（.）作为分隔符，不需要转义：
  SELECT SPLIT_INDEX('a.b.c.d', '.', 2); -- 返回 'c'
  
- **示例3：**
  反斜杠（\\）作为分隔符：
  反斜杠本身也需要转义，使用 '\\\\\\\\'：
  SELECT SPLIT_INDEX('a\\\\bc\\\\bd', '\\\\\\\\', 1); -- 返回 'bc'
  
 
 #### JSON_VAL函数说明
- 语法
```
STRING JSON_VAL(STRING json_string, STRING json_path)
```
表2参数说明 
| 参数          | 数据类型   | 说明                                                                            |
|:---|:---|:---|
| json_string | STRING | 需要解析的JSON对象，使用字符串表示。                                                          |
| json_path   | STRING | 解析JSON的路径表达式，使用字符串表示。 目前path支持如下表达式参考下表[表3]。 |
   
 表3json_path参数支持的表达式 
| 表达式  | 说明    |
|:---|:---|
| $    | 根对象   |
| \[\] | 数组下标  |
| \*   | 数组通配符 |
| .    | 取子元素  |
   
- 示例
  1. 测试输入数据。
     测试数据源kafka，具体消息内容参考如下：
     ```
     {name:James,age:24,gender:male,grade:{math:95,science:[80,85],english:100}}
     {name:James,age:24,gender:male,grade:{math:95,science:[80,85],english:100}]
     ```
     
  
  2. 使用JSON_VAL编写SQL
     ```
     CREATE TABLE kafkaSource (
       `message` string
     ) WITH (
       'connector' = 'kafka',
       'topic' = '<yourSourceTopic>',
       'properties.bootstrap.servers' = '<yourKafkaAddress1>:<yourKafkaPort>,<yourKafkaAddress2>:<yourKafkaPort>',
       'properties.group.id' = '<yourGroupId>',
       'scan.startup.mode' = 'latest-offset',
       "format" = "csv",
       "csv.field-delimiter" = "\u0001",
       "csv.quote-character" = "''"
     );
     CREATE TABLE kafkaSink(
       message1 STRING,
       message2 STRING,
       message3 STRING,
       message4 STRING,
       message5 STRING,  
       message6 STRING
     ) WITH (
       'connector' = 'kafka',
       'topic' = '<yourSinkTopic>',
       'properties.bootstrap.servers' = '<yourKafkaAddress1>:<yourKafkaPort>,<yourKafkaAddress2>:<yourKafkaPort>',
       "format" = "json"
     );
     insert into kafkaSink select 
     JSON_VAL(message,""),
     JSON_VAL(message,"$.name"),
     JSON_VAL(message,"$.grade.science"),
     JSON_VAL(message,"$.grade.science[*]"),
     JSON_VAL(message,"$.grade.science[1]"),JSON_VAL(message,"$.grade.dddd")
     from kafkaSource;
     ```
     
  
  3. 查看sink中kafka的topic中的输出结果
     ```
     {"message1":null,"message2":"swq","message3":"[80,85]","message4":"[80,85]","message5":"85","message6":null}
     {"message1":null,"message2":null,"message3":null,"message4":null,"message5":null,"message6":null}
     ```
     
   
 
