从非结构化字符串字段提取数据

已完成

安全日志数据通常包含在非结构化字符串字段中,需要进行分析才能提取数据。 在 KQL 中,可以通过多种方式从字符串字段提取信息。 使用的两个主要运算符是 extract 和 parse。

extract

extract 从文本字符串中获取正则表达式的匹配项。 可以选择将提取的子字符串转换为指定的类型。

print extract("x=([0-9.]+)", 1, "hello x=45.6|wo") == "45.6"

自变量

  • regex:正则表达式。

  • captureGroup:一个正 int 常数,指示待提取的捕获组。 “0”表示整个匹配项,“1”表示正则表达式中第一个“(‘括号’)”匹配的值,2 或以上的值表示后续括号。

  • text:要搜索的字符串。

  • typeLiteral:可选类型文本(例如 typeof(long))。 (如果支持)提取的子字符串将转换成此类型。

返回

如果 regex 在 text 中查找匹配项:与指定捕获组 captureGroup 匹配的子字符串可转换为 typeLiteral(可选)。

如果没有匹配项或类型转换失败,则为 null。

下面的示例使用 extract 函数从 SecurityEvent 表的“帐户”字段中提取“帐户名称”。

SecurityEvent
| where EventID == 4672 and AccountType == 'User'
| extend Account_Name = extract(@"^(.*\\)?([^@]*)(@.*)?$", 2, tolower(Account))
| summarize LoginCount = count() by Account_Name
| where Account_Name != ""
| where LoginCount < 10

parse

Parse 评估字符串表达式,并将其值解析为一个或多个计算列。 对于未成功分析的字符串,计算列的值将为 null。

语法

T | parse [kind=regex [flags=regex_flags] |simple|relaxed] Expression with * (StringConstant ColumnName [: ColumnType]) *

参数

  • T:输入表。

  • kind:

    • simple(默认值):StringConstant 为正则字符串值,匹配要求较为严格。 所有字符串分隔符都应出现在分析的字符串中,并且所有扩展列都必须与所需类型匹配。

    • regex:StringConstant 可能是正则表达式,匹配要求较为严格。 所有字符串分隔符(对于此模式,可以是正则表达式)都应出现在分析的字符串中,并且所有扩展列都必须与所需类型匹配。

    • flags:要在 regex 模式下使用的标志,如 RE2 标志中的 U(非贪婪)、m(多行模式)、s(匹配新行 \n)、i(不区分大小写)。

    • relaxed:StringConstant 为正则字符串值,匹配要求较为宽松。 所有字符串分隔符都应出现在分析的字符串中,但是扩展列可以部分匹配所需的类型。 与所需类型不匹配的扩展列将获得值 null。

  • Expression:计算结果为字符串的表达式。

  • ColumnName:要向其分配值的列的名称,从字符串表达式中提取。

  • ColumnType:可选。 一个标量值,指示要将值转换为何种类型。 默认为字符串类型。

返回

输入表,根据提供给运算符的列的列表进行扩展。

下面的语句演示 parse 运算符,该运算符计算字符串表达式并将其值分析为一个或多个计算列。 用于构造非结构化数据。

let Traces = datatable(EventText:string)
[
"Event: NotifySliceRelease (resourceName=PipelineScheduler, totalSlices=27, sliceNumber=23, lockTime=02/17/2016 08:40:01, releaseTime=02/17/2016 08:40:01, previousLockTime=02/17/2016 08:39:01)",
"Event: NotifySliceRelease (resourceName=PipelineScheduler, totalSlices=27, sliceNumber=15, lockTime=02/17/2016 08:40:00, releaseTime=02/17/2016 08:40:00, previousLockTime=02/17/2016 08:39:00)",
"Event: NotifySliceRelease (resourceName=PipelineScheduler, totalSlices=27, sliceNumber=20, lockTime=02/17/2016 08:40:01, releaseTime=02/17/2016 08:40:01, previousLockTime=02/17/2016 08:39:01)",
"Event: NotifySliceRelease (resourceName=PipelineScheduler, totalSlices=27, sliceNumber=22, lockTime=02/17/2016 08:41:01, releaseTime=02/17/2016 08:41:00, previousLockTime=02/17/2016 08:40:01)",
"Event: NotifySliceRelease (resourceName=PipelineScheduler, totalSlices=27, sliceNumber=16, lockTime=02/17/2016 08:41:00, releaseTime=02/17/2016 08:41:00, previousLockTime=02/17/2016 08:40:00)"
];
Traces  
| parse EventText with * "resourceName=" resourceName ", totalSlices=" totalSlices:long * "sliceNumber=" sliceNumber:long * "lockTime=" lockTime ", releaseTime=" releaseTime:date "," * "previousLockTime=" previousLockTime:date ")" *  
| project resourceName, totalSlices, sliceNumber, lockTime, releaseTime, previousLockTime