

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# FAST\$1REGEX\$1LOG\$1PARSER
<a name="sql-reference-fast-regex-log-parser"></a>

```
FAST_REGEX_LOG_PARSE('input_string', 'fast_regex_pattern')
```

FAST\$1REGEX\$1LOG\$1PARSE 的工作原理是首先将正则表达式分解为一系列正则表达式，一个用于组内的每个表达式，一个用于组外的每个表达式。任何表达式开头的任何固定长度部分都移动到前一个表达式的结尾。如果任何表达式的长度完全固定，则会与前一个表达式合并。然后，使用惰性语义计算一系列表达式，不回溯。（在正则表达式解析术语中，“惰性”意味着在每个步骤中解析的内容都不超过所需。“贪婪”意味着在每个步骤中尽可能多地解析。）

返回的列将 COLUMN1 通过 COLUMNn，其中 n 是正则表达式中的组数。这些列的类型将为 varchar(1024)。 请参阅下文中“第一个 FRLP 示例”和“更多 FRLP 示例”中的示例用法。

## FAST\$1REGEX\$1LOG\$1PARSER (FRLP)
<a name="w2aac22c23b7b9"></a>

FAST\$1REGEX\$1LOG\$1PARSER 使用惰性搜索，即在第一次匹配时停止搜索。相比之下，[REGEX\$1LOG\$1PARSE](sql-reference-regex-log-parse.md) 是贪婪的，除非使用了占有限定符。

FAST\$1REGEX\$1LOG\$1PARSE 会扫描所提供的输入字符串来查找 Fast Regex 模式指定的所有字符。 
+ 该输入字符串中的所有字符都必须由 Fast Regex 模式中定义的字符和扫描组来解释。扫描组定义扫描成功时的 fields-or-columns结果。
+ 如果在应用快速正则表达式模式时考虑了 input\$1string 中的所有字符，则 FRLP 将按顺序从该快速正则表达式模式中的每个带括号的表达式中创建一个输出字段（列）。 left-to-right第一个（最左边）带圆括号的表达式创建第一个输出字段，下一个（第二个）带圆括号的表达式创建第二个输出字段，直到最后一个带圆括号的表达式创建最后一个输出字段。 
+ 如果输入字符串包含任何未通过应用 Fast Regex 模式解释（匹配）的字符，则 FRLP 根本不会返回任何字段。

## Fast Regex 的字符类符号
<a name="w2aac22c23b7c11"></a>

Fast Regex 使用与常规正则表达式解析器不同的字符类符号集：


| 符号或构造 | 含义 | 
| --- | --- | 
|  -  |  字符范围，包括端点  | 
|  [ charclasses ]  |  字符类  | 
|  [^ charclasses ]  |  否定字符类  | 
|  \$1  |  Union  | 
|  &  |  交集  | 
|  ?  |  出现零次或一次  | 
|  \$1  |  出现零次或多次  | 
|  \$1  |  出现一次或多次  | 
|  \$1n\$1  |  出现 n 次  | 
|  \$1n,\$1  |  出现 n 次或更多次  | 
|  \$1n,m\$1  |  出现 n 到 m 次，包括这两者  | 
|  .  |  任何单个字符  | 
|  \$1  |  空白语言  | 
|  @  |  任何字符串  | 
|  "<Unicode string without double-quotes>"  |  字符串）  | 
|  ( )  |  空字符串）  | 
|  ( unionexp )  |  优先级覆盖  | 
|  < <identifier> >  |  命名模式  | 
|  <n-m>  |  数字间隔  | 
|  charexp:=<Unicode character>  |  单个非保留字符  | 
|  \$1 <Unicode character>  |  单个字符）  | 



我们支持使用以下 POSIX 标准标识符作为命名模式：

        <Digit>    -    "[0-9]"

        <Upper>    -    "[A-Z]"

        <Lower>    -    "[a-z]"

        <ASCII>    -    "[\$1u0000-\$1u007F]"

        <Alpha>    -    "<Lower>\$1<Upper>"

        <Alnum>    -    "<Alpha>\$1<Digit>"

        <Punct>    -    "[\$1\$1"\$1\$1%&'()\$1\$1,-./:;<=>?@[\$1\$1\$1]^\$1`\$1\$1\$1\$1]"

        <Blank>    -    "[ \$1t]"

        <Space>    -    "[ \$1t\$1n\$1f\$1r\$1u000B]"

        <Cntrl>    -    "[\$1u0000-\$1u001F\$1u007F]"

        < XDigit >-“0-9a-fa-f”

        <Print>    -    "<Alnum>\$1<Punct>"

        <Graph>    -    "<Print>"

 第一个 FRLP 示例

第一个示例使用 Fast Regex 模式 '(.\$1)\$1(.\$1.\$1)\$1.\$1'

```
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
```

1. input\$1string ('Mary\$1had\$1a\$1little\$1lamb') 的扫描从 Fast Regex 模式中定义的第一个组开始：(.\$1)，这意味着“查找任何字符 0 次或更多次。”  

    '**(.\$1)**\$1(.\$1.\$1)\$1.\$1'

1. 此组规范定义了要解析的第一列，要求 Fast Regex 日志解析器接受从输入字符串的第一个字符开始的输入字符串字符，直到在 Fast Regex 模式中找到下一个组或下一个不在组内（不在圆括号中）的文字字符或字符串。在此示例中，第一个组后面的下一文本字符为下划线： 

    '(.\$1)**\$1**(.\$1.\$1)\$1.\$1'

1. 解析器会扫描输入字符串中的每个字符，直到在 Fast Regex 模式中找到下一个规范：下划线：

    '(.\$1)\$1**(.\$1.\$1)**\$1.\$1'

1. 因此，Group-2 以“a\$1l”开头。接下来，解析器需要使用模式中的其余规范来确定此组的结尾：

    '(.\$1)\$1(.\$1.\$1)**\$1.\$1**'

**注意**  
在模式中指定但不在组内的字符字符串或文字必须可以在输入字符串中找到，但不会包含在任何输出字段中。  
如果 Fast Regex 模式省略了最后一个星号，则不会得到任何结果。

## 更多 FRLP 示例
<a name="furtherExamples"></a>

下一个示例使用的是“\$1”，表示重复最后一个表达式 1 次或多次（“\$1”表示 0 次或多次）。

### 示例 A
<a name="w2aac22c23b7c13b4"></a>

在本例中，最长的前缀是第一个下划线。第一 field/column 组将在 “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
```

前面的示例不返回任何字段，因为 “\$1” 需要至少还有一个字段 underscore-in-a-row；而 input\$1string 没有该字段。

### 示例 B
<a name="w2aac22c23b7c13b6"></a>

在以下示例中，由于采用了惰性语义，“\$1”是多余的：

```
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
```

 上一个示例成功返回两个字段，因为在找到“\$1\$1”规范所需的多条下划线后，组 2 规范 (.\$1) 接受 .input\$1string 中的所有剩余字符。下划线不会出现在“Mary”后面，也不会出现在“had”前面，因为“\$1\$1”规范没有用圆括号括起来。

（正如简介中提到的，在正则表达式解析术语中，“惰性”意味着在每个步骤中解析的内容都不超过所需。“贪婪”意味着在每个步骤中尽可能多地解析。）

本主题中的第一个示例 A 失败，因为当它到达第一条下划线时，正则表达式处理器在没有回溯的情况下无法获知它无法使用下划线来匹配“\$1\$1”并且 FRLP 将不回溯，而 [REGEX\$1LOG\$1PARSE](sql-reference-regex-log-parse.md) 将回溯。 

正上方的搜索 B 变成了三次搜索：

```
(.*)_
_*(._
.*)
```

请注意，第二个字段组在第二次和第三次搜索之间被拆分，“\$1\$1” 也被认为与 “\$1\$1\$1” 相同（也就是说，它认为 “下划线重复下划线-underscore-1-” 与 “下划线重复下划线重复下划线-underscore-or-more-times 0-” 相同。）or-more-times

示例 A 演示了 REGEX\$1LOG\$1PARSE 和 FAST\$1REGEX\$1LOG\$1PARSE 之间的主要区别，因为 A 中的搜索将使用 REGEX\$1LOG\$1PARSE，因为该函数将使用回溯。

### 示例 C
<a name="w2aac22c23b7c13b8"></a>

在以下示例中，加号不是多余的，因为“<Alpha>（任何字母字符）”的长度是固定的，因此将用作“\$1”搜索的分隔符。

```
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)。