Извлечение данных из неструктурированных строковых полей

Завершено

Данные журнала безопасности часто содержатся в неструктурированных строковых полях и требуют синтаксического анализа для извлечения данных. Существует несколько способов извлечения данных из строковых полей в KQL. Используются два основных оператора: извлечение и синтаксический анализ.

Экстракт

Извлечение находит совпадение для регулярного выражения из текстовой строки. Вы можете при необходимости преобразовать извлеченную подстроку в указанный тип.

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

Аргументы

  • regex: регулярное выражение.

  • captureGroup: положительная константа int, указывающая группу захвата для извлечения. Значение "0" означает все совпадение, значение "1" для значения, соответствующего первому "("скобка")" в регулярном выражении, 2 или более для последующих скобок.

  • текст: строка для поиска.

  • typeLiteral: необязательный типовой литерал (например, typeof(long)). Если указан, то извлеченная подстрока преобразуется в этот тип.

Возвраты

Если regex находит совпадение в тексте: подстрока, соответствующая указанной группе захвата captureGroup, с необязательным преобразованием в typeLiteral.

Если совпадения нет, или преобразование типа завершается ошибкой: null.

В следующем примере используется функция извлечения имени учетной записи из поля "Учетная запись" таблицы 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

Анализировать

Функция разбора вычисляет строковое выражение и разбирает его значение в одном или нескольких вычисленных столбцах. Вычисляемые столбцы имеют значения NULL для неудачно проанализированных строк.

Синтаксис

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

Аргументы

  • T: входная таблица.

  • добрый:

    • simple (по умолчанию): StringConstant — это обычное строковое значение, и соответствие строгое. Все строковые разделители должны присутствовать в проанализированной строке, и все расширенные столбцы должны соответствовать требуемым типам.

    • regex: StringConstant может быть регулярным выражением, и соответствие строгое. Все строковые разделители, которые могут быть регулярными выражениями при использовании этого режима, должны присутствовать в проанализированной строке, и все расширенные столбцы должны соответствовать требуемым типам.

    • флаги: флаги, которые будут использоваться в режиме регулярных выражений, например U (Ungreedy), m (многострочный режим), s (соответствие новой строке \n), i (без учета регистра) в формате флагов RE2.

    • упрощённое: StringConstant — это регулярное строковое значение, и сопоставление выполнено с меньшей строгостью. Все разделители строк должны отображаться в строке синтаксического анализа, но расширенные столбцы могут частично соответствовать необходимым типам. Расширенные столбцы, не соответствующие требуемым типам, получают значение NULL.

  • Выражение: выражение, которое вычисляется строкой.

  • ColumnName: имя столбца для назначения значения, извлеченного из строкового выражения.

  • ColumnType: необязательно. Скалярное значение, указывающее тип, в который необходимо преобразовать значение. По умолчанию используется тип строки.

Возвраты

Входная таблица, развернутая в соответствии со списком столбцов, которые были предоставлены оператором.

В следующем заявлении демонстрируется оператор парсинга, который вычисляет строковое выражение и анализирует его значение в один или несколько вычисляемых столбцов. Используется для структурирования неструктурированных данных.

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