# WPL 语言参考
本文档提供 WPL 的完整语言元素参考,用于快速查阅类型、语法和结构。
---
## 📑 文档导航
| [类型系统](#-类型系统) | 所有数据类型速查表 |
| [语法元素](#-语法元素) | 基本结构、字段定义、格式控制 |
| [子字段语法](#-子字段语法) | JSON、KV、数组子字段 |
| [JSON-like 路由](#-json-like-路由) | `json_like`、`json`、`bad_json` 的配合方式 |
| [注解](#-注解) | tag、copy_raw 注解 |
| [语法速查](#-语法速查) | 常用模式快速参考 |
---
## 📋 类型系统
### 基础类型
| 1 | 预读符号 | `peek_symbol(xxx)` | `peek_symbol(GET)` | 预读但不消费 |
| 2 | 忽略 | `_` | `_`, `2*_`, `3*_` | 忽略该字段 |
| 3 | 符号 | `symbol(xxx)` | `symbol(HTTP)` | 精确匹配 |
| 4 | 布尔 | `bool` | `true`, `false` | 布尔值 |
| 5 | 字符串 | `chars` | `"hello"` | 任意字符串 |
| 6 | 整数 | `digit` | `123`, `8080` | 整数 |
| 7 | 浮点 | `float` | `3.14`, `0.01` | 浮点数 |
| 8 | 序列号 | `sn` | `ABC123XYZ` | 自动生成序列号 |
### 时间类型
| 9 | 通用时间 | `time` | `2023-05-15 07:09:12` | 自动识别多种格式 |
| 10 | ISO 8601 | `time_iso` | `2023-05-15T07:09:12Z` | ISO 8601 标准 |
| 11 | RFC 3339 | `time_3339` | `2022-03-21T12:34:56+00:00` | RFC3339 标准 |
| 12 | RFC 2822 | `time_2822` | `Mon, 07 Jul 2025 09:20:32 +0000` | 邮件时间格式 |
| 13 | CLF 时间 | `time/clf` | `06/Aug/2019:12:12:19 +0800` | Apache/Nginx 日志 |
| 14 | Unix时间戳 | `time_timestamp` | `1647849600` | Unix 秒级时间戳 |
### 网络类型
| 15 | IP地址 | `ip` | `192.168.1.100`, `::1` | IPv4/IPv6 地址 |
| 16 | IP网段 | `ip_net` | `192.168.0.0/24` | CIDR 网段 |
| 17 | 域名 | `domain` | `example.com` | 域名 |
| 18 | 邮箱 | `email` | `user@example.com` | 邮箱地址 |
| 19 | 端口 | `port` | `8080`, `443` | 端口号 |
| 20 | URL | `url` | `http://example.com/path` | 完整 URL |
### 编码类型
| 21 | 十六进制 | `hex` | `48656c6c6f` | 十六进制数据 |
| 22 | Base64 | `base64` | `aGVsbG8=` | Base64 编码 |
### 结构化类型
| 23 | 键值对 | `kvarr` | `key=value` | KV 格式 |
| 24 | JSON | `json` | `{"k":"v"}` | JSON 对象 |
| 25 | 严格JSON | `exact_json` | `{"k":"v"}` | 严格验证 JSON |
| 26 | 对象 | `obj` | 嵌套对象 | 通用对象 |
| 27 | 数组 | `array` | `[1,2,3]` | 数组 |
| 28 | 数字数组 | `array/digit` | `[1,2,3]` | 数字数组 |
| 29 | 字符串数组 | `array/chars` | `["a","b"]` | 字符串数组 |
### 协议类型
| 30 | HTTP请求 | `http/request` | `GET /path HTTP/1.1` | HTTP 请求行 |
| 31 | HTTP状态 | `http/status` | `200`, `404` | HTTP 状态码 |
| 32 | User-Agent | `http/agent` | `Mozilla/5.0...` | 浏览器 UA |
| 33 | HTTP方法 | `http/method` | `GET`, `POST` | HTTP 方法 |
### 特殊类型
| 34 | 身份证 | `id_card` | `110101199001011234` | 18 位身份证 |
| 35 | 手机号 | `mobile_phone` | `13800138000` | 11 位手机号 |
| 36 | 协议文本 | `proto_text` | 协议格式 | 协议文本解析 |
| 37 | 自动识别 | `auto` | 自动推断 | 自动类型推断 |
---
## 🔧 语法元素
### 基本结构
```wpl
package 包名 {
rule 规则名 {
|预处理管道|
(字段列表)
}
}
```
### 字段定义完整语法
```
[N*] DataType [ (symbol) ] [ (subfields) ] [:name] [ [len] ] [ format ] [ sep ] { | pipe }
```
| `[N*]` | 重复计数 | `kvarr`, `3*ip` |
| `DataType` | 数据类型 | `digit`, `ip`, `json` |
| `(symbol)` | 符号内容 | `symbol(GET)` |
| `(subfields)` | 子字段列表 | `json(chars@name)` |
| `:name` | 字段命名 | `:status`, `:client_ip` |
| `[len]` | 长度限制 | `[100]` |
| `format` | 格式控制 | `<[,]>`, `"`, `^10` |
| `sep` | 分隔符 | `\,`, `\;`, `\0` |
| `\| pipe` | 管道函数 | `\|f_has(name)\|` |
### 格式控制
| 范围定界 | `<beg,end>` | `<[,]>`, `<{,}>` | 起止符号 |
| 引号 | `"` | `chars"` | 引号包裹 |
| 字符计数 | `N*` | `10*chars`, `5*_` | 按字符数 |
### 分组元信息
| `seq` | 顺序匹配(默认) | `seq(ip, digit, time)` | 按顺序依次匹配 |
| `alt` | 择一匹配 | `alt(ip, digit)` | 匹配其中一个 |
| `opt` | 可选匹配 | `opt(chars:tag)` | 分组失败不报错 |
| `some_of` | 尽可能多 | `some_of(ip, digit)` | 循环匹配 |
### 分隔符优先级
```
字段级(3) > 组级(2) > 上游(1)
```
| 逗号 | `\,` | 逗号分隔 | 字段级 (3) |
| 分号 | `\;` | 分号分隔 | 字段级 (3) |
| 冒号 | `\:` | 冒号分隔 | 字段级 (3) |
| 空格 | `\s` | 空格分隔 | 字段级 (3) |
| 行尾 | `\0` | 读到行尾 | 字段级 (3) |
| 组分隔 | `(...)\sep` | 组级分隔 | 组级 (2) |
| 默认 | 无 | 继承上游 | 上游 (1) |
---
## 🎯 子字段语法
### JSON 子字段
```wpl
json(type@key, type@key, ...)
```
**示例:**
```wpl
# 基本提取
json(chars@name, digit@age)
# 嵌套路径
json(chars@user/name, digit@user/age)
# 可选字段
json(chars@name, opt(chars)@email)
```
### `bad_json`
```wpl
bad_json:name
```
**说明:**
- `bad_json` 输出的是原始文本,字段类型为 `chars`
- 适合接住“看起来像 JSON,但严格解析失败”的输入
- 推荐与 `json_like` 预处理一起使用,避免把普通文本误判为坏 JSON
**示例:**
```wpl
(bad_json:raw)
```
---
## 🧩 JSON-like 路由
### `json_like` 预处理
```wpl
|json_like|
```
**语义:**
- 这是规则前置的行 pipe
- 只做轻量 sniff,判断当前输入是否“像 JSON”
- 它不会提取字段,也不会做完整 JSON 解析
`json_like` 适合放在兜底规则前面,为 `bad_json` 提供保护。
### `json` 的内置 sniff
`json` 现在已经内置了 `json_like` 式的快速判断,所以:
```wpl
rule good_json {
(json(chars@host, chars@method))
}
```
不需要再额外写:
```wpl
rule good_json {
|json_like|
(json(chars@host, chars@method))
}
```
### 推荐写法
当你希望把“合法 JSON”和“坏 JSON”分开处理时,推荐这样写:
```wpl
rule good_json {
(json(chars@host, chars@method))
}
rule broken_json {
|json_like|
(bad_json:raw)
}
```
这套写法的行为是:
- 合法 JSON:由 `json(...)` 规则命中
- 损坏但像 JSON:由 `json_like + bad_json` 规则兜底
- 普通文本:不会被 `bad_json` 吃掉
### 性能含义
- `json_like` 是轻量判断,适合做前置过滤
- `json` 已经内置快速 sniff,因此对普通文本的拒绝成本明显更低
- 对“像 JSON 但损坏”的输入,先做 `json_like` 再走 `bad_json` 才有意义
### KV 子字段
```wpl
kvarr(type@key, type@key, ...)
```
**示例:**
```wpl
kvarr(chars@hostname, digit@port, opt(chars)@user)
```
### 数组
```wpl
array[/subtype]
```
**示例:**
```wpl
array/digit:nums # [1,2,3]
array/chars:items # ["a","b"]
array/array/digit # 嵌套数组
```
---
## 📝 注解
### tag 注解
```wpl
#[tag(key1:"value1", key2:"value2")]
package demo {
rule x { (digit, time) }
}
```
### copy_raw 注解
```wpl
#[copy_raw(name:"raw_log")]
rule nginx_log {
(ip, time, chars)
}
```
### 原始字符串(避免转义)
```wpl
#[tag(path:r#"C:\Program Files\App"#)]
package demo {
rule x { (digit) }
}
```
---
## 💡 语法速查
### 常用模式
```wpl
# 字段命名
type:name # digit:status
# 忽略字段
_ # 忽略 1 个
N*_ # 忽略 N 个
# 重复模式
kvarr # 自动解析KV
N*ip # 固定 N 次
# 可选分组
opt(chars:tag) # 单个可选分组
opt(kvarr) # 可选 KV 分组
# 格式控制
<[,]> # 方括号包裹
" # 引号包裹
^10 # 固定 10 字符
# 分隔符
\, # 逗号
\; # 分号
\0 # 行尾
# 子字段
json(chars@key) # JSON 字段
kvarr(digit@port) # KV 字段
@path/to/field # 嵌套路径
```
---
## 相关文档
- 快速入门:[01-quickstart.md](./01-quickstart.md)
- 核心概念:[02-core-concepts.md](./02-core-concepts.md)
- 实战指南:[03-practical-guide.md](./03-practical-guide.md)
- 函数参考:[05-functions-reference.md](./05-functions-reference.md)
- 语法规范:[06-grammar-reference.md](./06-grammar-reference.md)