Извлечение данных из неструктурированных строковых полей
Данные журнала безопасности часто содержатся в неструктурированных строковых полях и требуют синтаксического анализа для извлечения данных. Существует несколько способов извлечения данных из строковых полей в 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