本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
FAST_REGEX_LOG_PARSER
FAST_REGEX_LOG_PARSE('input_string', 'fast_regex_pattern')
FAST_REGEX_LOG_PARSE 的工作原理是首先将正则表达式分解为一系列正则表达式,一个用于组内的每个表达式,一个用于组外的每个表达式。任何表达式开头的任何固定长度部分都将移至前一个表达式的末尾。如果任何表达式的长度完全固定,则将其与先前的表达式合并。然后,使用惰性语义对一系列表达式进行评估,无需回溯。(用正则表达式解析的话来说,“懒惰” 意味着每一步解析的次数不要超过你需要的量。 “Greedy” 意味着在每个步骤中尽可能多地解析。)
返回的列将是 ColumnN 中的 COLUMN1,其中 n 是正则表达式中的组数。这些列的类型将为 varchar (1024)。 请参阅下文中“第一个 FRLP 示例”和“更多 FRLP 示例”中的示例用法。
FAST_REGEX_LOG_PARSER (FRLP)
FAST_REGEX_LOG_PARSER 使用延迟搜索——它会在第一场比赛时停止。相比之下,除非使用所有格量词,否则REGEX_LOG_PARSE是贪婪的。
FAST_REGEX_LOG_PARSE 会扫描提供的输入字符串以查找 Fast Regex 模式指定的所有字符。
-
该输入字符串中的所有字符都必须由 Fast Regex 模式中定义的字符和扫描组构成。扫描组定义扫描成功时的 fields-or-columns结果。
-
如果在应用 Fast Regex 模式时将 input_string 中的所有字符都考虑在内,则 FRLP 会按 left-to-right 顺序从该 Fast Regex 模式中的每个括号表达式创建输出字段(列)。第一个(最左边)括号表达式创建第一个输出字段,下一个(第二个)圆括号表达式创建第二个输出字段,从最后一个括号表达式向上创建最后一个输出字段。
-
如果 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” 开头出现,因为 “_+” 规范未包含在圆括号中。
正如介绍中提到的,正则表达式解析术语中的 “懒惰” 意味着每一步解析的次数不要超过你需要的量;“Greedy” 意味着在每个步骤中尽可能多地解析。
本主题中的第一个示例 A 失败,因为当它到达第一条下划线时,正则表达式处理器在没有回溯的情况下无法获知它无法使用下划线来匹配“_+”并且 FRLP 将不回溯,而 REGEX_LOG_PARSE 将回溯。
正上方的搜索 B 变成了三次搜索:
(.*)_ _*(._ .*)
请注意,第二个字段组在第二次和第三次搜索之间分开,“_+” 也被视为 “__*” 相同(也就是说,它认为 “下划线重复下划线-1-or-more-times” 与 “下划线重复下划线-0-or-more-times” 相同。)
案例 A 展示了 REGEX_LOG_PARSE 和 FAST_REGEX_LOG_PARSE 之间的主要区别,因为 A 中的搜索将在 REGEX_LOG_PARSE 下起作用,因为该函数将使用回溯功能。
在这个例子中
在以下示例中,加号不是多余的,因为“<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>' '.*$'
使用懒散语义依次进行匹配。
返回的列将是 ColumnN 中的 COLUMN1,其中 n 是正则表达式中的组数。这些列的类型将为 varchar (1024)。