Tips dan pemecahan masalah saat menulis parser
Dokumen ini menjelaskan masalah yang mungkin Anda alami saat menulis kode parser.
Saat menulis kode parser, Anda mungkin mengalami error saat petunjuk penguraian tidak berfungsi seperti yang diharapkan. Situasi yang mungkin menghasilkan error meliputi hal berikut:
- Pola
Grok
gagal - Operasi
rename
ataureplace
gagal - Error sintaksis dalam kode parser
Praktik umum dalam kode parser
Bagian berikut menjelaskan praktik terbaik, tips, dan solusi untuk membantu memecahkan masalah.
Hindari penggunaan titik atau tanda hubung dalam nama variabel
Penggunaan tanda hubung dan titik dalam nama variabel dapat menyebabkan perilaku yang tidak terduga,
sering kali saat melakukan operasi merge
untuk menyimpan nilai di kolom UDM. Anda juga mungkin mengalami masalah penguraian yang terputus-putus.
Misalnya, jangan gunakan nama variabel berikut:
my.variable.result
my-variable-result
Sebagai gantinya, gunakan nama variabel berikut: my_variable_result
.
Jangan gunakan istilah dengan makna khusus sebagai nama variabel
Kata tertentu, seperti event
dan timestamp
, dapat memiliki arti khusus dalam kode
parser.
String event
sering digunakan untuk mewakili satu kumpulan data UDM dan digunakan dalam
pernyataan @output
. Jika pesan log menyertakan kolom yang disebut event
, atau
jika Anda menentukan variabel perantara yang disebut event
, dan
kode parser menggunakan kata event
dalam pernyataan @output
, Anda akan mendapatkan
pesan error tentang konflik nama.
Ganti nama variabel perantara menjadi nama lain, atau gunakan istilah event1
sebagai
awalan dalam nama kolom UDM dan dalam pernyataan @output
.
Kata timestamp
mewakili stempel waktu yang dibuat dari log mentah asli. Nilai yang ditetapkan dalam variabel perantara ini disimpan ke kolom UDM metadata.event_timestamp
. Istilah @timestamp
mewakili tanggal
dan waktu log mentah diuraikan untuk membuat data UDM.
Contoh berikut menetapkan kolom UDM metadata.event_timestamp
ke tanggal
dan waktu log mentah diuraikan.
# Save the log parse date and time to the timestamp variable
mutate {
rename => {
"@timestamp" => "timestamp"
}
}
Contoh berikut menetapkan kolom UDM metadata.event_timestamp
ke tanggal dan
waktu yang diekstrak dari log mentah asli dan disimpan dalam variabel
perantara when
.
# Save the event timestamp to timestamp variable
mutate {
rename => {
"when" => "timestamp"
}
}
Jangan gunakan istilah berikut sebagai variabel:
- collectiontimestamp
- createtimestamp
- event
- filename
- pesan
- namespace
- output
- onerrorcount
- timestamp
- zona waktu
Menyimpan setiap nilai data di kolom UDM terpisah
Jangan menyimpan beberapa kolom dalam satu kolom UDM dengan menggabungkannya dengan pemisah. Berikut adalah contohnya:
"principal.user.first_name" => "first:%{first_name},last:%{last_name}"
Sebagai gantinya, simpan setiap nilai di kolom UDM terpisah.
"principal.user.first_name" => "%{first_name}"
"principal.user.last_name" => "%{last_name}"
Menggunakan spasi, bukan tab, dalam kode
Jangan gunakan tab dalam kode parser. Hanya gunakan spasi dan indentasi 2 spasi sekaligus.
Jangan melakukan beberapa tindakan penggabungan dalam satu operasi
Jika Anda menggabungkan beberapa kolom dalam satu operasi, hal ini dapat menyebabkan
hasil yang tidak konsisten. Sebagai gantinya, tempatkan pernyataan merge
ke dalam operasi
terpisah.
Misalnya, ganti contoh berikut:
mutate {
merge => {
"security_result.category_details" => "category_details"
"security_result.category_details" => "super_category_details"
}
}
Dengan ini:
mutate {
merge => {
"security_result.category_details" => "category_details"
}
}
mutate {
merge => {
"security_result.category_details" => "super_category_details"
}
}
Memilih ekspresi bersyarat if
versus if else
Jika nilai kondisional yang Anda uji hanya dapat memiliki satu kecocokan,
gunakan pernyataan kondisional if else
. Pendekatan ini sedikit lebih
efisien. Namun, jika Anda memiliki skenario saat nilai yang diuji dapat cocok lebih
dari sekali, gunakan beberapa pernyataan if
yang berbeda dan urutkan pernyataan
dari kasus yang paling umum ke kasus yang paling spesifik.
Memilih kumpulan file log yang representatif untuk menguji perubahan parser
Praktik terbaiknya adalah menguji kode parser menggunakan contoh log mentah dengan berbagai format. Hal ini memungkinkan Anda menemukan log unik atau kasus ekstrem yang mungkin perlu ditangani oleh parser.
Menambahkan komentar deskriptif ke kode parser
Tambahkan komentar ke kode parser yang menjelaskan mengapa pernyataan tersebut penting, bukan apa yang dilakukan pernyataan tersebut. Komentar membantu siapa pun yang mengelola parser untuk mengikuti alur. Berikut adalah contohnya:
# only assign a Namespace if the source address is RFC 1918 or Loopback IP address
if [jsonPayload][id][orig_h] =~ /^(127(?:\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))\{3\}$)|(10(?:\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))\{3\}$)|(192\.168(?:\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))\{2\}$)|(172\.(?:1[6-9]|2\d|3[0-1])(?:\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))\{2\}$)/ {
mutate {
replace => {
"event1.idm.read_only_udm.principal.namespace" => "%{resource.labels.project_id}"
}
}
}
Melakukan inisialisasi variabel perantara lebih awal
Sebelum mengekstrak nilai dari log mentah asli, lakukan inisialisasi variabel perantara yang akan digunakan untuk menyimpan nilai pengujian.
Tindakan ini mencegah error ditampilkan yang menunjukkan bahwa variabel perantara tidak ada.
Pernyataan berikut menetapkan nilai dalam variabel product
ke
kolom UDM metadata.product_name
.
mutate{
replace => {
"event1.idm.read_only_udm.metadata.product_name" => "%{product}"
}
}
Jika variabel product
tidak ada, Anda akan mendapatkan error berikut:
"generic::invalid_argument: pipeline failed: filter mutate (4) failed: replace failure: field \"event1.idm.read_only_udm.metadata.product_name\": source field \"product\": field not set"
Anda dapat menambahkan pernyataan on_error
untuk menangkap error. Berikut adalah contohnya:
mutate{
replace => {
"event1.idm.read_only_udm.metadata.product_name" => "%{product}"
}
on_error => "_error_does_not_exist"
}
Contoh pernyataan sebelumnya berhasil menangkap error penguraian ke dalam
variabel perantara boolean, yang disebut _error_does_not_exist
. Hal ini tidak
memungkinkan Anda menggunakan variabel product
dalam pernyataan bersyarat, misalnya if
.
Berikut adalah contohnya:
if [product] != "" {
mutate{
replace => {
"event1.idm.read_only_udm.metadata.product_name" => "%{product}"
}
}
on_error => "_error_does_not_exist"
}
Contoh sebelumnya menampilkan error berikut karena klausa bersyarat if
tidak mendukung pernyataan on_error
:
"generic::invalid_argument: pipeline failed: filter conditional (4) failed: failed to evaluate expression: generic::invalid_argument: "product" not found in state data"
Untuk mengatasi hal ini, tambahkan blok pernyataan terpisah yang menginisialisasi variabel
perantara sebelum menjalankan pernyataan filter ekstraksi (json
, csv
, xml
, kv
, atau grok
).
Berikut adalah contohnya.
filter {
# Initialize intermediate variables for any field you will use for a conditional check
mutate {
replace => {
"timestamp" => ""
"does_not_exist" => ""
}
}
# load the logs fields from the message field
json {
source => "message"
array_function => "split_columns"
on_error => "_not_json"
}
}
Cuplikan kode parser yang diperbarui menangani beberapa skenario menggunakan
pernyataan kondisional untuk memeriksa apakah kolom tersebut ada. Selain itu, pernyataan on_error
menangani error yang mungkin terjadi.
Mengonversi SHA-256 ke base64
Contoh berikut mengekstrak nilai SHA-256, mengenkodenya dalam base64, mengonversi data yang dienkode menjadi string heksadesimal, lalu mengganti kolom tertentu dengan nilai yang diekstrak dan diproses.
if [Sha256] != ""
{
base64
{
encoding => "RawStandard"
source => "Sha256"
target => "base64_sha256"
on_error => "base64_message_error"
}
mutate
{
convert =>
{
"base64_sha256" => "bytestohex"
}
on_error => "already_a_string"
}
mutate
{
replace =>
{
"event.idm.read_only_udm.network.tls.client.certificate.sha256" => "%{base64_sha256}"
"event.idm.read_only_udm.target.resource.name" => "%{Sha256}"
}
}
}
Menangani error dalam pernyataan parser
Log yang masuk sering kali memiliki format log yang tidak terduga atau data yang tidak diformat dengan benar.
Anda dapat mem-build parser untuk menangani error ini. Praktik terbaiknya adalah menambahkan pengendali on_error
ke filter ekstraksi, lalu menguji variabel perantara sebelum melanjutkan ke segmen logika parser berikutnya.
Contoh berikut menggunakan filter ekstraksi json
dengan pernyataan
on_error
untuk menetapkan variabel boolean _not_json
. Jika _not_json
ditetapkan ke
true
, artinya entri log yang masuk tidak dalam format JSON yang valid dan
entri log tidak berhasil diuraikan. Jika variabel _not_json
adalah false
, entri log yang masuk dalam format JSON yang valid.
# load the incoming log from the default message field
json {
source => "message"
array_function => "split_columns"
on_error => "_not_json"
}
Anda juga dapat menguji apakah kolom memiliki format yang benar. Contoh berikut
memeriksa apakah _not_json
ditetapkan ke true
, yang menunjukkan bahwa log tidak dalam
format yang diharapkan.
# Test that the received log matches the expected format
if [_not_json] {
drop { tag => "TAG_MALFORMED_MESSAGE" }
} else {
# timestamp is always expected
if [timestamp] != "" {
# ...additional parser logic goes here …
} else {
# if the timestamp field does not exist, it's not a log source
drop { tag => "TAG_UNSUPPORTED" }
}
}
Hal ini memastikan bahwa penguraian tidak gagal jika log diserap dengan format yang salah untuk jenis log yang ditentukan.
Gunakan filter drop
dengan variabel tag
sehingga kondisinya dicatat dalam tabel Metrik proses transfer di BigQuery.
TAG_UNSUPPORTED
TAG_MALFORMED_ENCODING
TAG_MALFORMED_MESSAGE
TAG_NO_SECURITY_VALUE
Filter drop
menghentikan parser memproses log mentah, menormalisasi kolom, dan membuat data UDM. Log mentah asli masih diserap ke Google Security Operations
dan dapat ditelusuri menggunakan penelusuran log mentah di Google Security Operations.
Nilai yang diteruskan ke variabel tag
disimpan di kolom drop_reason_code
' di
tabel Metrik proses transfer. Anda dapat menjalankan kueri ad hoc terhadap tabel yang mirip dengan berikut:
SELECT
log_type,
drop_reason_code,
COUNT(drop_reason_code) AS count
FROM `datalake.ingestion_metrics`
GROUP BY 1,2
ORDER BY 1 ASC
Memecahkan masalah error validasi
Saat mem-build parser, Anda mungkin mengalami error yang terkait dengan validasi, misalnya, kolom wajib diisi tidak ditetapkan dalam data UDM. Error ini mungkin terlihat mirip dengan berikut:
Error: generic::unknown: invalid event 0: LOG_PARSING_GENERATED_INVALID_EVENT: "generic::invalid_argument: udm validation failed: target field is not set"
Kode parser berhasil dieksekusi, tetapi data UDM yang dihasilkan tidak menyertakan semua kolom UDM yang diperlukan seperti yang ditentukan oleh nilai yang ditetapkan ke metadata.event_type
. Berikut
contoh tambahan yang dapat menyebabkan error ini:
- Jika
metadata.event_type
adalahUSER_LOGIN
dan kolom UDMtarget.user value
tidak ditetapkan. - Jika
metadata.event_type
adalahNETWORK_CONNECTION
dan kolom UDMtarget.hostname
tidak ditetapkan.
Untuk informasi selengkapnya tentang kolom UDM metadata.event_type
dan kolom
yang diperlukan, lihat panduan penggunaan UDM.
Salah satu opsi untuk memecahkan masalah jenis error ini adalah dengan memulai dengan menetapkan nilai statis ke kolom UDM. Setelah Anda menentukan semua kolom UDM yang diperlukan, periksa log mentah asli untuk melihat nilai mana yang akan diuraikan dan disimpan ke data UDM. Jika log mentah asli tidak berisi kolom tertentu, Anda mungkin perlu menetapkan nilai default.
Berikut adalah contoh template, khusus untuk jenis peristiwa USER_LOGIN
, yang
menggambarkan pendekatan ini.
Perhatikan berikut ini:
- Template ini melakukan inisialisasi variabel perantara dan menetapkan setiap variabel ke string statis.
- Kode di bagian Penetapan Kolom menetapkan nilai dalam variabel perantara ke kolom UDM.
Anda dapat memperluas kode ini dengan menambahkan variabel perantara dan kolom UDM tambahan. Setelah Anda mengidentifikasi semua kolom UDM yang harus diisi, lakukan hal berikut:
Di bagian Input Configuration, tambahkan kode yang mengekstrak kolom dari log mentah asli dan menetapkan nilai ke variabel perantara.
Di bagian Date Extract, tambahkan kode yang mengekstrak stempel waktu peristiwa dari log mentah asli, mengubahnya, dan menetapkannya ke variabel perantara.
Sesuai kebutuhan, ganti nilai yang diinisialisasi yang ditetapkan di setiap variabel median menjadi string kosong.
filter {
mutate {
replace => {
# UDM > Metadata
"metadata_event_timestamp" => ""
"metadata_vendor_name" => "Example"
"metadata_product_name" => "Example SSO"
"metadata_product_version" => "1.0"
"metadata_product_event_type" => "login"
"metadata_product_log_id" => "12345678"
"metadata_description" => "A user logged in."
"metadata_event_type" => "USER_LOGIN"
# UDM > Principal
"principal_ip" => "192.168.2.10"
# UDM > Target
"target_application" => "Example Connect"
"target_user_user_display_name" => "Mary Smith"
"target_user_userid" => "mary@example.com"
# UDM > Extensions
"auth_type" => "SSO"
"auth_mechanism" => "USERNAME_PASSWORD"
# UDM > Security Results
"securityResult_action" => "ALLOW"
"security_result.severity" => "LOW"
}
}
# ------------ Input Configuration --------------
# Extract values from the message using one of the extraction filters: json, kv, grok
# ------------ Date Extract --------------
# If the date {} function is not used, the default is the normalization process time
# ------------ Field Assignment --------------
# UDM Metadata
mutate {
replace => {
"event1.idm.read_only_udm.metadata.vendor_name" => "%{metadata_vendor_name}"
"event1.idm.read_only_udm.metadata.product_name" => "%{metadata_product_name}"
"event1.idm.read_only_udm.metadata.product_version" => "%{metadata_product_version}"
"event1.idm.read_only_udm.metadata.product_event_type" => "%{metadata_product_event_type}"
"event1.idm.read_only_udm.metadata.product_log_id" => "%{metadata_product_log_id}"
"event1.idm.read_only_udm.metadata.description" => "%{metadata_description}"
"event1.idm.read_only_udm.metadata.event_type" => "%{metadata_event_type}"
}
}
# Set the UDM > auth fields
mutate {
replace => {
"event1.idm.read_only_udm.extensions.auth.type" => "%{auth_type}"
}
merge => {
"event1.idm.read_only_udm.extensions.auth.mechanism" => "auth_mechanism"
}
}
# Set the UDM > principal fields
mutate {
merge => {
"event1.idm.read_only_udm.principal.ip" => "principal_ip"
}
}
# Set the UDM > target fields
mutate {
replace => {
"event1.idm.read_only_udm.target.user.userid" => "%{target_user_userid}"
"event1.idm.read_only_udm.target.user.user_display_name" => "%{target_user_user_display_name}"
"event1.idm.read_only_udm.target.application" => "%{target_application}"
}
}
# Set the UDM > security_results fields
mutate {
merge => {
"security_result.action" => "securityResult_action"
}
}
# Set the security result
mutate {
merge => {
"event1.idm.read_only_udm.security_result" => "security_result"
}
}
# ------------ Output the event --------------
mutate {
merge => {
"@output" => "event1"
}
}
}
Mengurai teks tidak terstruktur menggunakan fungsi Grok
Saat menggunakan fungsi Grok untuk mengekstrak nilai dari teks tidak terstruktur, Anda dapat menggunakan pola Grok yang telah ditentukan sebelumnya dan pernyataan ekspresi reguler. Pola Grok
membuat kode lebih mudah dibaca. Jika ekspresi reguler tidak menyertakan karakter
singkat (seperti \w
, \s
), Anda dapat menyalin dan menempelkan pernyataan langsung
ke dalam kode parser.
Karena pola Grok adalah lapisan abstraksi tambahan dalam pernyataan, pola tersebut dapat membuat pemecahan masalah menjadi lebih kompleks saat Anda mengalami error. Berikut adalah contoh fungsi Grok yang berisi pola Grok dan ekspresi reguler yang telah ditentukan sebelumnya.
grok {
match => {
"message" => [
"%{NUMBER:when}\\s+\\d+\\s%{SYSLOGHOST:srcip} %{WORD:action}\\/%{NUMBER:returnCode} %{NUMBER:size} %{WORD:method} (?P<url>\\S+) (?P<username>.*?) %{WORD}\\/(?P<tgtip>\\S+).*"
]
}
}
Pernyataan ekstraksi tanpa pola Grok mungkin memiliki performa yang lebih baik. Misalnya, contoh berikut memerlukan kurang dari setengah langkah pemrosesan untuk dicocokkan. Untuk sumber log yang berpotensi memiliki volume tinggi, ini adalah pertimbangan yang penting.
Memahami perbedaan antara ekspresi reguler RE2 dan PCRE
Parser Google Security Operations menggunakan RE2 sebagai mesin ekspresi reguler. Jika sudah terbiasa dengan sintaksis PCRE, Anda mungkin melihat perbedaan. Berikut adalah salah satu contohnya:
Berikut adalah pernyataan PCRE: (?<_custom_field>\w+)\s
Berikut adalah pernyataan RE2 untuk kode parser: (?P<_custom_field>\\w+)\\s
Pastikan untuk meng-escape karakter escape
Google Security Operations menyimpan data log mentah yang masuk dalam format yang dienkode JSON. Hal ini untuk
memastikan bahwa string karakter yang tampak seperti singkatan ekspresi reguler
diinterpretasikan sebagai string literal. Misalnya, \t
ditafsirkan sebagai
string literal, bukan karakter tab.
Contoh berikut adalah log mentah asli dan log format yang dienkode JSON.
Perhatikan karakter escape yang ditambahkan di depan setiap karakter garis miring terbalik
yang mengelilingi istilah entry
.
Berikut adalah log mentah asli:
field=\entry\
Berikut adalah log yang dikonversi ke format yang dienkode JSON:
field=\\entry\\
Saat menggunakan ekspresi reguler dalam kode parser, Anda harus menambahkan karakter escape tambahan jika hanya ingin mengekstrak nilai. Untuk mencocokkan garis miring terbalik dalam log mentah asli, gunakan empat garis miring terbalik dalam pernyataan ekstraksi.
Berikut adalah ekspresi reguler untuk kode parser:
^field=\\\\(?P<_value>.*)\\\\$
Berikut adalah hasil yang dihasilkan. Grup bernama _value
menyimpan istilah entry
:
"_value": "entry"
Saat memindahkan pernyataan ekspresi reguler standar ke kode parser, hindari
karakter singkatan ekspresi reguler dalam pernyataan ekstraksi.
Misalnya, ubah \s
menjadi \\s
.
Jangan ubah karakter khusus ekspresi reguler saat melakukan escape ganda dalam
pernyataan ekstraksi. Misalnya, \\
tetap tidak berubah sebagai \\
.
Berikut adalah ekspresi reguler standar:
^.*?\\\"(?P<_user>[^\\]+)\\\"\s(?:(logged\son|logged\soff))\s.*?\\\"(?P<_device>[^\\]+)\\\"\.$
Ekspresi reguler berikut diubah agar berfungsi dalam kode parser.
^.*?\\\"(?P<_user>[^\\\\]+)\\\"\\s(?:(logged\\son|logged\\soff))\\s.*?\\\"(?P<_device>[^\\\\]+)\\\"\\.$
Tabel berikut merangkum kapan ekspresi reguler standar harus menyertakan karakter escape tambahan sebelum menyertakannya dalam kode parser.
Regular expression | Ekspresi reguler yang dimodifikasi untuk kode parser | Deskripsi perubahan |
---|---|---|
\s |
\\s |
Karakter singkatan harus di-escape. |
\. |
\\. |
Karakter yang dicadangkan harus di-escape. |
\\" |
\\\" |
Karakter yang dicadangkan harus di-escape. |
\] |
\\] |
Karakter yang dicadangkan harus di-escape. |
\| |
\\| |
Karakter yang dicadangkan harus di-escape. |
[^\\]+ |
[^\\\\]+ |
Karakter khusus dalam grup class karakter harus di-escape. |
\\\\ |
\\\\ |
Karakter khusus di luar grup class karakter atau karakter singkatan tidak memerlukan escape tambahan. |
Ekspresi reguler harus menyertakan grup tangkapan yang dinamai
Ekspresi reguler, seperti "^.*$"
, adalah sintaksis RE2 yang valid. Namun, dalam kode
parser, kode tersebut gagal dengan error berikut:
"ParseLogEntry failed: pipeline failed: filter grok (0) failed: failed to parse data with all match
patterns"
Anda harus menambahkan grup tangkapan yang valid ke ekspresi. Jika Anda menggunakan pola Grok, pola ini akan menyertakan grup tangkapan bernama secara default. Saat menggunakan penggantian ekspresi reguler, pastikan untuk menyertakan grup bernama.
Berikut adalah contoh ekspresi reguler dalam kode parser:
"^(?P<_catchall>.*$)"
Berikut adalah hasilnya, yang menampilkan teks yang ditetapkan ke grup bernama _catchall
.
"_catchall": "User \"BOB\" logged on to workstation \"DESKTOP-01\"."
Gunakan grup bernama generik untuk memulai saat Anda membuat ekspresi
Saat membuat pernyataan ekstraksi, mulailah dengan ekspresi yang menangkap lebih dari yang Anda inginkan. Kemudian, luaskan ekspresi satu kolom dalam satu waktu.
Contoh berikut dimulai dengan menggunakan grup bernama (_catchall
) yang cocok dengan seluruh pesan. Kemudian, ekspresi akan dibuat secara bertahap dengan mencocokkan
bagian tambahan teks. Dengan setiap langkah, grup bernama _catchall
akan berisi lebih sedikit teks asli. Lanjutkan dan lakukan iterasi satu langkah demi satu langkah untuk
mencocokkan pesan hingga Anda tidak lagi memerlukan grup bernama _catchall
.
Langkah | Ekspresi reguler dalam kode parser | Output grup pengambilan bernama _catchall |
---|---|---|
1 | "^(?P<_catchall>.*$)" |
User \"BOB\" logged on to workstation \"DESKTOP-01\". |
2 | ^User\s\\\"(?P<_catchall>.*$) |
BOB\" logged on to workstation \"DESKTOP-01\". |
3 | ^User\s\\\"(?P<_user>.*?)\\\"\s(?P<_catchall>.*$) |
logged on to workstation \"DESKTOP-01\". |
Lanjutkan hingga ekspresi cocok dengan seluruh string teks. |
Meng-escape karakter singkatan dalam ekspresi reguler
Ingatlah untuk meng-escape karakter singkatan ekspresi reguler saat menggunakan
ekspresi dalam kode parser. Berikut adalah contoh string teks dan
ekspresi reguler standar yang mengekstrak kata pertama, This
.
This is a sample log.
Ekspresi reguler standar berikut mengekstrak kata pertama, This
.
Namun, saat Anda menjalankan ekspresi ini dalam kode parser, hasilnya tidak memiliki huruf
s
.
Ekspresi reguler standar | Output grup pengambilan bernama _firstWord |
---|---|
"^(?P<_firstWord>[^\s]+)\s.*$" |
"_firstWord": "Thi", |
Hal ini karena ekspresi reguler dalam kode parser memerlukan karakter escape tambahan
yang ditambahkan ke karakter singkatan. Pada contoh sebelumnya, \s
harus diubah menjadi \\s
.
Regular expression yang direvisi untuk kode parser | Output grup pengambilan bernama _firstWord |
---|---|
"^(?P<_firstWord>[^\\s]+)\\s.*$" |
"_firstWord": "This", |
Hal ini hanya berlaku untuk karakter singkatan, seperti \s
, \r
, dan \t
.
Karakter lain, seperti ``, tidak perlu di-escape lebih lanjut.
Contoh lengkap
Bagian ini menjelaskan aturan sebelumnya sebagai contoh menyeluruh. Berikut adalah string teks yang tidak terstruktur, dan ekspresi reguler standar yang ditulis untuk mengurai string. Terakhir, ini mencakup ekspresi reguler yang dimodifikasi yang berfungsi dalam kode parser.
Berikut adalah string teks asli.
User "BOB" logged on to workstation "DESKTOP-01".
Berikut adalah ekspresi reguler RE2 standar yang mengurai string teks.
^.*?\\\"(?P<_user>[^\\]+)\\\"\s(?:(logged\son|logged\soff))\s.*?\\\"(?P<_device>[^\\]+)\\\"\.$
Ekspresi ini mengekstrak kolom berikut.
Grup pencocokan | Posisi karakter | String teks |
---|---|---|
Kecocokan penuh | 0-53 | User \"BOB\" logged on to workstation \"DESKTOP-01\". |
Grup `_user` | 7-10 | BOB |
Grup 2. | 13-22 | logged on |
Grup `_device` | 40-50 | DESKTOP-01 |
Ini adalah ekspresi yang diubah. Ekspresi reguler RE2 standar dimodifikasi agar berfungsi dalam kode parser.
^.*?\\\"(?P<_user>[^\\\\]+)\\\"\\s(?:(logged\\son|logged\\soff))\\s.*?\\\"(?P<_device>[^\\\\]+)\\\"\\.$
Perlu bantuan lain? Dapatkan jawaban dari anggota Komunitas dan profesional Google SecOps.