Files
QieKan-3.0/docs/dev/syntax.md
T

264 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 规则语法详解 (Rule Syntax)
[[toc]]
Legado 支持多种规则语法,可在源的不同字段中混合使用。本文档详细介绍每种语法的写法和使用场景。
## 1. JSOUP 默认规则 (Default)
`@` 为分隔符的 CSS 选择器语法,是 Legado 最常用的规则类型。
### 基本结构
每段规则可分为 3 部分,用 `.` 连接:
```
类型.名称.位置
```
| 部分 | 说明 | 示例 |
|:---|:-----------------|:-------------------------------------|
| 类型 | 选择器类型 | `class``id``tag``text``children` |
| 名称 | 匹配值 | `odd``content``a` |
| 位置 | 索引(从 0 开始,负数为倒数) | `0``-1` |
**示例:**
```
class.odd.0@tag.a.0@text // 取 class="odd" 的第一个元素下第一个 <a> 标签的文本
tag.div.-1@text // 取最后一个 <div> 的文本
```
### 最后一段为获取内容
| 值 | 说明 |
|:------------|:------------|
| `text` | 文本内容 |
| `textNodes` | 文本节点列表 |
| `ownText` | 自身文本(不含子元素) |
| `href` | 链接地址 |
| `src` | 图片/资源地址 |
| `html` | HTML 内容 |
| `all` | 全部内容 |
### 排除符号 `!`
`!` 排除不需要的元素,多个排除用 `:` 分隔:
```
tag.div!0:2@text // 排除第 1 个和第 3 个 div
```
### 列表倒置 `-`
在获取列表的最前面加 `-` 可使列表倒置,适用于网站目录列表本身是倒序的情况:
```
-tag.dd@tag.a@text // 倒序获取所有 dd 下的 a 标签文本
```
### 正则替换 `##`
在规则末尾添加 `##正则表达式##替换内容`
```
tag.p@text##去除的文字##替换为的文字
tag.p@text##要去除的文字 // 替换内容为空时可省略第二个 ##
```
### 数组写法 `[index]`
支持类似数组的索引选择:
| 写法 | 说明 |
|:-----------|:--------------|
| `[0]` | 第一个元素 |
| `[-1]` | 最后一个元素 |
| `[0:3]` | 前 3 个元素 |
| `[2:5]` | 第 3 到第 5 个元素 |
| `[0:10:2]` | 每隔一个取一个 |
| `[!0:2]` | 排除第 1 个和第 3 个 |
| `[-1:0]` | 反转列表 |
### 连接符号
| 符号 | 说明 | 示例 |
|:-------|:---------------|:------------------------------|
| `\|\|` | 优先取第一个有值的结果 | `tag.a@text\|\|tag.span@text` |
| `&&` | 合并所有取到的值 | `tag.a@text&&tag.span@text` |
| `%%` | 交替取值(依次从各列表中取) | `tag.a@href%%tag.a@text` |
::: tip 使用限制
连接符号只能在同种规则间使用,不包括 js 和正则。
:::
## 2. JSOUP CSS 选择器 (CSS Selector)
`@css:` 开头的标准 CSS 选择器语法。
```
@css:选择器@获取内容
```
**示例:**
```
@css:.book-list li@text // 获取 class="book-list" 下所有 li 的文本
@css:#content p@html // 获取 id="content" 下所有 p 的 HTML
@css:[property=og:image]@content // 获取 meta 标签的 content 属性
```
- 在线测试:[Try jsoup online](https://try.jsoup.org/)
## 3. JSONPath 路径表达式
`@json:``$.` 开头的 JSON 数据提取语法。
```
@json:表达式
$.表达式
```
**示例:**
```
$.data.books[*] // 获取所有书籍
$.data.books[0].title // 获取第一本书的标题
$..books[*] // 递归查找所有 books 数组
$.info.Datas // 获取 info 下的 Datas
```
- 在线测试:[Jayway JsonPath Evaluator](http://jsonpath.herokuapp.com/)
## 4. XPath 路径表达式
`@XPath:``//` 开头的 XML/HTML 路径表达式。
```
@XPath:表达式
//表达式
```
**示例:**
```
//div[@class="book-list"]/ul/li // 获取指定 class 下的列表项
//*[@property="og:novel:author"]/@content // 获取 meta 标签属性
//a[text()="阅读"]/@href // 获取特定文本链接的 href
```
详细语法参见 [XPath 路径表达式](./xpath)。
## 5. JavaScript 脚本
`<js></js>``@js:` 中使用 JavaScript。
| 形式 | 使用位置 | 说明 |
|:------------|:----------------|:-----------------------|
| `@js:` | 只能放在其他规则的**最后** | 将前面规则的结果作为 `result` 变量 |
| `<js></js>` | 任意位置 | 可作为其他规则的分隔符 |
**示例:**
```
@css:.book@text@js:result.replace("旧", "新") // 先取文本再用 JS 处理
tag.li<js></js>//a // JS 作为分隔符
@js:java.base64Encode(key) // 纯 JS 表达式
```
### 在搜索/发现列表中使用
`+` 开头可使用 AllInOne 规则,在搜索列表、发现列表和目录中使用。
## 6. 正则表达式
Legado 中有三种正则用法:
### 全部匹配 (AllInOne)
- 只能在搜索列表、发现列表、详情页预加载和目录列表中使用
- 必须以 `:` 开头
```
:<正则表达式>
```
**示例(目录页):**
```
-:<li><a[^\"]+\"([^\"]*)\">([^<]*) // 提取链接和标题,- 前缀表示倒序
```
### 单一匹配 (OnlyOne)
形式:`##正则表达式##替换内容###`
- 只能在搜索列表、发现列表、详情页预加载、目录列表**之外**使用
- 只获取**第一个**匹配结果并替换
**示例(详情页):**
```
##:book_name"[^"]+"([^"]+)"##$1### // 提取书名
```
### 净化(循环替换)
形式:`##正则表达式##替换内容`
- 跟在其他规则后面,对结果进行循环匹配替换
- 独立使用相当于 `all##正则表达式##替换内容`
**示例(正文页):**
```
@css:.content@html##<script>.*?</script>## // 移除所有 script 标签
```
## 7. `{{}}` 模板变量
### 在搜索 URL 和发现 URL 中
`{{}}` 内只能使用 JavaScript
```
/search?key={{key}}&page={{page}}
/search?key={{java.base64Encode(key)}}&page={{(page-1)*20}}
```
### 在其他规则中
`{{}}` 内可使用任意规则,默认为 JS。使用其他规则需要标志头:
| 规则类型 | 标志头 |
|:---------|:-----------------|
| JS(默认) | 无需标志 |
| Default | `@@` |
| XPath | `@xpath:``//` |
| JSONPath | `@json:``$.` |
| CSS | `@css:` |
### `{}` 旧语法
保留的阅读 2.0 语法,只能使用 JSONPath,建议避免使用。
## 8. 变量存取
### `@put` 与 `@get`
只能在 JS 以外的规则中使用:
```
@put:{bid:"//*[@bid-data]/@bid-data"} // 存储变量
@get:bid // 读取变量
```
### `java.put` 与 `java.get`
只能在 JS 中使用(JS 中无法使用 `@get`):
```js
java.put('key', 'value') // 存储
java.get('key') // 读取
```