本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
FAST_REGEX_LOG_PARSER
FAST_REGEX_LOG_PARSE('input_string', 'fast_regex_pattern')
FAST_REGEX_LOG_PARSE 的工作原理是首先将正则表达式分解为一系列正则表达式,一个用于组内的每个表达式,一个用于组外的每个表达式。任何表达式开头处的任何固定长度部分都将移至前一个表达式的末尾。如果任何表达式的长度完全固定,则将其与前一个表达式合并。然后使用没有回溯的懒惰语义对一系列表达式进行评估。(用正则表达式解析的话来说,“懒惰” 意味着每一步解析的次数都不要超过你需要的范围。 “贪婪” 意味着在每一步都尽可能多地解析。)
返回的列将是 COLUMN1 到 ColumnN,其中 n 是正则表达式中的组数。这些列的类型将为 varchar (1024)。 请参阅下文中“第一个 FRLP 示例”和“更多 FRLP 示例”中的示例用法。
FAST_REGEX_LOG_PARSER (FRLP)
FAST_REGEX_LOG_PARSER 使用延迟搜索——它会在第一场比赛时停止。相比之下,REGEX_LOG_PARSE除非使用所有格量词,否则是贪婪的。
FAST_REGEX_LOG_PARSE 在提供的输入字符串中扫描快速正则表达式模式指定的所有字符。
-
该输入字符串中的所有字符都必须由 Fast Regex 模式中定义的字符和扫描组来解释。扫描组定义 fields-or-columns扫描成功时生成。
-
如果在应用 Fast Regex 模式时考虑了 input_string 中的所有字符,则 FRLP 会根据该快速正则表达式中的每个圆括号表达式创建一个输出字段(列) left-to-right ORDER。第一个(最左边)括号表达式创建第一个输出字段,下一个(第二个)圆括号表达式创建第二个输出字段,直到最后一个括号表达式创建最后一个输出字段。
-
如果 input_string 包含任何未通过应用 Fast Regex 模式解释(匹配)的字符,则 FRLP 根本不返回任何字段。
快速正则表达式的字符类符号
Fast Regex 使用了一组与常规正则表达式解析器不同的字符类符号:
| 符号或构造 | 意义 |
|---|---|
|
- |
字符范围,包括端点 |
|
[角色类] |
字符类 |
|
[^ 字符类] |
否定的字符类 |
|
| |
Union |
|
& |
十字路口 |
|
? |
匹配零或一个匹配项 |
|
* |
匹配零或多个匹配项 |
|
+ |
一个或多个匹配项 |
|
{n} |
n 匹配项 |
|
{n,} |
n 或多个匹配项 |
|
{n, m} |
n 到 m 次出现次数,包括两者 |
|
. |
任何单个字符 |
|
# |
空的语言 |
|
@ |
任何字符串 |
|
"<Unicode string without double-quotes>" |
一个字符串) |
|
( ) |
空字符串) |
|
(unionexp) |
优先顺序 |
|
< <identifier> > |
命名模式 |
|
<n-m> |
数值间隔 |
|
charexp:=<Unicode character> |
单个非保留字符 |
|
\ <Unicode character> |
单个字符) |
我们支持以下 POSIX 标准标识符作为命名模式:
<Digit> - "[0-9]"
<Upper> - "[A-Z]"
<Lower> - "[a-z]"
<ASCII> - "[\u0000-\u007F]"
<Alpha> - "<Lower>|<Upper>"
<Alnum> - "<Alpha>|<Digit>"
<Punct> - "[!\"#$%&'()*+,-./:;<=>?@[\\\]^_`{|}~]"
<Blank> - "[ \t]"
<Space> - "[ \t\n\f\r\u000B]"
<Cntrl> - "[\u0000-\u001F\u007F]"
<XDigit> - "0-9a-fA-F"
<Print> - "<Alnum>|<Punct>"
<Graph> - "<Print>"
第一个 FRLP 示例
第一个示例使用 Fast Regex 模式 '(.*)_(._.*)_.*'
select t.r."COLUMN1", t.r."COLUMN2" from . . . . . . . . . . . . .> (values (FAST_REGEX_LOG_PARSE('Mary_had_a_little_lamb', '(.*)_(._.*)_.*'))) t(r); +------------------------+-----------------------+ | COLUMN1 | COLUMN2 | +------------------------+-----------------------+ | Mary_had | a_little_lamb | +------------------------+-----------------------+ 1 row selected
-
input_string ('Mary_had_a_little_lamb') 的扫描从 Fast Regex 模式中定义的第一个组开始:(.*),这意味着“查找任何字符 0 次或更多次。”
'(.*)_(._.*)_.*'
-
这个组规范定义了要解析的第一列,它要求 Fast Regex Log Parser 接受从输入字符串的第一个字符开始的输入字符串字符,直到它在 Fast Regex 模式中找到下一个组或下一个不在组中的文字字符或字符串(不在括号)。在此示例中,第一个组后面的下一文本字符为下划线:
'(.*)_(._.*)_.*'
-
解析器扫描输入字符串中的每个字符,直到找到 Fast Regex 模式中的下一个规范:下划线:
'(.*)_(._.*)_.*'
-
因此,组 2 以 “a_l” 开头。接下来,解析器需要使用模式中的剩余规范来确定该组的结尾:
'(.*)_(._.*)_.*'
在模式中指定但不在组内指定的字符串或文字必须在输入字符串中找到,但不能包含在任何输出字段中。
如果 Fast Regex 模式省略了最后的星号,则不会获得任何结果。
更多的 FRLP 示例
下一个示例使用 “+”,这意味着重复最后一个表达式 1 次或多次(“*” 表示 0 次或多次)。
示例 A
在这个例子中,最长的前缀是第一个下划线。第一个字段/列组将在 “Mary” 上匹配,第二个字段/列组不匹配。
select t.r."COLUMN1", t.r."COLUMN2" from . . . . . . . . . . . . .> (values (FAST_REGEX_LOG_PARSE('Mary_had_a_little_lamb', '(.*)_+(._.*)'))) t(r); +----------+----------+ | COLUMN1 | COLUMN2 | +----------+----------+ +----------+----------+ No rows selected
前面的示例不返回任何字段,因为必填的 “+” 至少还有一个字段 underscore-in-a-row; 而且 input_string 没有那个。
示例 B
在以下情况下,'+'是多余的,因为语义很懒惰:
select t.r."COLUMN1", t.r."COLUMN2" from . . . . . . . . . . . . .> (values (FAST_REGEX_LOG_PARSE('Mary____had_a_little_lamb', '(.*)_+(.*)'))) t(r); +-------------------------+-------------------------+ | COLUMN1 | COLUMN2 | +-------------------------+-------------------------+ | Mary | had_a_little_lamb | +-------------------------+-------------------------+ 1 row selected
上一个示例成功返回两个字段,因为在找到“_+”规范所需的多条下划线后,组 2 规范 (.*) 接受 .input_string 中的所有剩余字符。下划线不在 “Mary” 后面,也不会在 “had” 开头,因为 “_+” 规范没有用括号括起来。
正如导言中提到的,正则表达式解析术语中的 “懒惰” 意味着每一步解析的次数都不要超过你需要的范围;“贪婪” 意味着在每一步都尽可能多地解析。
本主题中的第一个示例 A 失败,因为当它到达第一条下划线时,正则表达式处理器在没有回溯的情况下无法获知它无法使用下划线来匹配“_+”并且 FRLP 将不回溯,而 REGEX_LOG_PARSE 将回溯。
正上方的搜索 B 变成了三个搜索:
(.*)_ _*(._ .*)
请注意,第二个字段组在第二次和第三次搜索之间被分开,而且 “_+” 被认为与 “__*” 相同(也就是说,它认为 “下划线 repeat-underscore-1-or-more-times“同样” 下划线下划线 repeat-underscore-0-or-more-times“。)
案例 A 演示了 REGEX_LOG_PARSE 和 FAST_REGEX_LOG_PARSE 之间的主要区别,因为 A 中的搜索可以在 REGEX_LOG_PARSE 下运行,因为该函数会使用回溯法。
示例 C
在以下示例中,加号不是多余的,因为“<Alpha>(任何字母字符)”的长度是固定的,因此将用作“+”搜索的分隔符。
select t.r."COLUMN1", t.r."COLUMN2" from . . . . . . . . . . . . .> (values (FAST_REGEX_LOG_PARSE('Mary____had_a_little_lamb', '(.*)_+(<Alpha>.*)'))) t(r); +----------------------------+----------------------------+ | COLUMN1 | COLUMN2 | +----------------------------+----------------------------+ | Mary | had_a_little_lamb | +----------------------------+----------------------------+ 1 row selected '(.*) +(<Alpha>.*)' gets converted into three regular expressions: '.* ' ' *<Alpha>' '.*$'
每个都使用懒惰语义依次匹配。
返回的列将是 COLUMN1 到 ColumnN,其中 n 是正则表达式中的组数。这些列的类型将为 varchar (1024)。