:orphan:
rex
rex 命令使用正则表达式命名捕获组从原始文本字段中提取字段。它使用 Java 正则表达式模式。有关更多信息,请参阅 Java 正则表达式文档。
rex 和 parse 命令的比较
rex 和 parse 命令都使用带有命名捕获组的 Java 正则表达式从文本字段中提取信息。下表比较了 rex 和 parse 命令的功能。
| 特性 | rex |
parse |
|---|---|---|
| 模式类型 | Java 正则表达式 | Java 正则表达式 |
| 是否需要命名组 | 是 | 是 |
| 多个命名组 | 是 | 否 |
| 多次匹配 | 是 | 否 |
| 文本替换 | 是 | 否 |
| 偏移量跟踪 | 是 | 否 |
| 组名中的特殊字符 | 否 | 否 |
语法
rex 命令的语法如下:
rex [mode=<mode>] field=<field> <pattern> [max_match=<int>] [offset_field=<string>]
参数
rex 命令支持以下参数。
| 参数 | 必需/可选 | 描述 |
|---|---|---|
field |
必需 | 要从中提取数据的字段。该字段必须是字符串类型。 |
<pattern> |
必需 | 用于提取新字段的带有命名捕获组的正则表达式模式。模式必须至少包含一个使用 (?<name>pattern) 语法的命名捕获组。组名必须以字母开头,且只能包含字母和数字。 |
mode |
可选 | 模式匹配模式。有效值为 extract 和 sed。extract 模式从正则表达式命名捕获组创建新字段。sed 模式使用 sed 风格的样式执行文本替换(支持带有标志的 s/pattern/replacement/、y/from_chars/to_chars/ 音译以及反向引用)。 |
max_match |
可选 | 要提取的最大匹配数。如果值大于 1,则提取的字段以数组形式返回。值为 0 表示无限制匹配;但是,有效匹配数会自动受配置的最大值限制。默认最大值为 10,可通过 plugins.ppl.rex.max_match.limit 进行配置(参见 注释)。默认值为 1。 |
offset_field |
可选 | 仅在 extract 模式下有效。用于存储匹配项字符偏移位置的字段名称。 |
您可以在 plugins.ppl.rex.max_match.limit 集群设置中设置 max_match 限制。有关更多信息,请参阅 SQL 设置。不建议将此限制设置为较大的值,因为这可能导致内存消耗过大,特别是对于匹配空字符串的模式(例如 \d* 或 \w*)。
示例 1:基本文本提取
以下查询使用命名捕获组从电子邮件地址中提取用户名和域名。两个提取的字段都以字符串形式返回:
source=accounts
| rex field=email "(?<username>[^@]+)@(?<domain>[^.]+)"
| fields email, username, domain
| head 2
该查询返回以下结果:
| email | username | domain | | — | — | — | | amberduke@pyrami.com | amberduke | pyrami | | hattiebond@netagy.com | hattiebond | netagy |
示例 2:处理不匹配的模式
以下查询显示,rex 命令会返回所有事件,对于不匹配的模式,将提取的字段设置为 null。当找到匹配项时,提取的字段以字符串形式返回:
source=accounts
| rex field=email "(?<user>[^@]+)@(?<domain>gmail\\.com)"
| fields email, user, domain
| head 2
该查询返回以下结果:
| email | user | domain | | — | — | — | | amberduke@pyrami.com | null | null | | hattiebond@netagy.com | null | null |
示例 3:使用 max_match 提取多个单词
以下查询使用带有 max_match 参数的 rex 命令从 address 字段中提取多个单词。提取的字段以字符串数组形式返回:
source=accounts
| rex field=address "(?<words>[A-Za-z]+)" max_match=2
| fields address, words
| head 3
该查询返回以下结果:
| address | words | | — | — | | 880 Holmes Lane | [Holmes,Lane] | | 671 Bristol Street | [Bristol,Street] | | 789 Madison Street | [Madison,Street] |
示例 4:使用 sed 模式替换文本
以下查询在 sed 模式下使用 rex 命令通过文本替换来替换电子邮件域名。提取的字段以字符串形式返回:
source=accounts
| rex field=email mode=sed "s/@.*/@company.com/"
| fields email
| head 2
该查询返回以下结果:
| email | | — | | amberduke@company.com | | hattiebond@company.com |
示例 5:使用 offset_field 跟踪匹配位置
以下查询跟踪匹配发生的字符位置。提取的字段以字符串形式返回,offset_field 也以字符串形式返回:
source=accounts
| rex field=email "(?<username>[^@]+)@(?<domain>[^.]+)" offset_field=matchpos
| fields email, username, domain, matchpos
| head 2
该查询返回以下结果:
| email | username | domain | matchpos | | — | — | — | — | | amberduke@pyrami.com | amberduke | pyrami | domain=10-15&username=0-8 | | hattiebond@netagy.com | hattiebond | netagy | domain=11-16&username=0-9 |
示例 6:提取复杂的电子邮件模式
以下查询提取完整的电子邮件组件,包括顶级域名。所有提取的字段都以字符串形式返回:
source=accounts
| rex field=email "(?<user>[a-zA-Z0-9._%+-]+)@(?<domain>[a-zA-Z0-9.-]+)\\.(?<tld>[a-zA-Z]{2,})"
| fields email, user, domain, tld
| head 2
该查询返回以下结果:
| email | user | domain | tld | | — | — | — | — | | amberduke@pyrami.com | amberduke | pyrami | com | | hattiebond@netagy.com | hattiebond | netagy | com |
示例 7:链接多个 rex 命令
以下查询从名和姓中提取首字母。所有提取的字段都以字符串形式返回:
source=accounts
| rex field=firstname "(?<firstinitial>^.)"
| rex field=lastname "(?<lastinitial>^.)"
| fields firstname, lastname, firstinitial, lastinitial
| head 3
该查询返回以下结果:
| firstname | lastname | firstinitial | lastinitial | | — | — | — | — | | Amber | Duke | A | D | | Hattie | Bond | H | B | | Nanette | Bates | N | B |
示例 8:捕获组命名限制
以下查询显示捕获组的命名限制。由于 Java 正则表达式 的限制,组名不能包含下划线。
带有下划线的无效 PPL 查询:
source=accounts
| rex field=email "(?<user_name>[^@]+)@(?<email_domain>[^.]+)"
| fields email, user_name, email_domain
该查询返回以下结果:
{'reason': 'Invalid Query', 'details': "Invalid capture group name 'user_name'. Java regex group names must start with a letter and contain only letters and digits.", 'type': 'IllegalArgumentException'}
Error: Query returned no data
不带下划线的正确 PPL 查询:
source=accounts
| rex field=email "(?<username>[^@]+)@(?<emaildomain>[^.]+)"
| fields email, username, emaildomain
| head 2
该查询返回以下结果:
| email | username | emaildomain | | — | — | — | | amberduke@pyrami.com | amberduke | pyrami | | hattiebond@netagy.com | hattiebond | netagy |
示例 9:max_match 限制强制执行
以下查询显示 max_match 限制保护机制。当 max_match 设置为 0(无限制)时,系统会自动强制执行最大匹配数限制,以防止内存耗尽。
带有 max_match=0 的 PPL 查询自动限制为默认值 10:
source=accounts
| rex field=address "(?<digit>\\d*)" max_match=0
| eval digit_count=array_length(digit)
| fields address, digit_count
| head 1
该查询返回以下结果:
| address | digit_count | | — | — | | 880 Holmes Lane | 10 |
超过配置限制的 PPL 查询会导致错误:
source=accounts
| rex field=address "(?<digit>\\d*)" max_match=100
| fields address, digit
| head 1
该查询返回以下结果:
{'reason': 'Invalid Query', 'details': 'Rex command max_match value (100) exceeds the configured limit (10). Consider using a smaller max_match value or adjust the plugins.ppl.rex.max_match.limit setting.', 'type': 'IllegalArgumentException'}
Error: Query returned no data
有关详细的 Java 正则表达式模式语法和用法,请参阅 官方 Java Pattern 文档。