ast-grep 语法速查表
版本unknown 更新日志2026-01-13 GitHubast-grep/ast-grep
340px

🎯 模式语法 >>>

ast-grep 使用模式代码构建 AST 树并匹配目标代码

模式匹配

a + 1
可匹配嵌套表达式:const b = a + 1、funcCall(a + 1)、deeplyNested({ target: a + 1 })

元变量

$META_VARIABLE
以 $ 开头,后跟大写字母 A-Z、下划线 _ 或数字 1-9,匹配单个 AST 节点

有效元变量

$META, $META_VAR, $META_VAR1, $_, $_123

无效元变量

$invalid, $Svalue, $123, $KEBAB-CASE, $

🔤 多元变量 >>>

使用 $$$ 匹配零个或多个 AST 节点

函数参数

console.log($$$ARGS)
console.log()                       // 匹配零个节点
console.log('hello world')          // 匹配一个节点
console.log('debug: ', key, value)  // 匹配多个节点
console.log(...args)                // 匹配展开运算符

函数参数

function $FUNC($$$ARGS) { $$$ }
function foo(bar) { return bar }
function noop() {}
function add(a, b, c) { return a + b + c }

🎯 元变量捕获 >>>

相同名称的元变量匹配相同内容

捕获示例

$A == $A
// 匹配这些
a == a
1 + 1 == 1 + 1

// 不匹配这些
a == b
1 + 1 == 2

非捕获匹配

$_FUNC($_FUNC)
以下划线开头的元变量不会被捕获,可优化匹配速度

⚛️ 原子规则 >>>

定义最基本的匹配规则,确定语法节点是否匹配

pattern

rule:
  pattern: console.log($GREETING)
根据模式语法匹配单个语法节点

Pattern Object

pattern:
  selector: field_definition
  context: class A { $FIELD = $INIT }
使用对象指定在更大上下文中的子语法节点

strictness

pattern:
  strictness: cst  # cst, smart, ast, relaxed, signature
控制模式匹配策略:cst(最严格)、smart(默认)、ast、relaxed、signature(最宽松)

🏷️ kind 规则 >>>

指定 tree-sitter 解析器定义的 AST 节点类型

基本用法

rule:
  kind: field_definition
class Test {
  a = 123  // 匹配此行
}

常用 kind 名称

kind: if_statement
kind: expression
kind: function_declaration
kind: class_declaration
可在 ast-grep playground 中查看完整的 kind 名称

🔍 regex 规则 >>>

使用正则表达式匹配节点文本内容

基本用法

rule:
  regex: 'prototype'
匹配文本内容包含 'prototype' 的节点

组合使用

rule:
  kind: pair
  has:
    field: key
    regex: 'prototype'
var a = {
  prototype: anotherObject  // 匹配
}

🔢 nthChild 规则 >>>

匹配第 N 个子节点

基本用法

rule:
  pattern: $A
  nthChild:
    position: 1
    of: expression_statement
匹配作为 expression_statement 第一个子节点的节点

位置选项

nthChild:
  position: 0       # 第一个子节点(从0开始)
  of: statement_list

📏 range 规则 >>>

匹配特定行范围内的节点

基本用法

rule:
  pattern: $A
  range:
    start: 10
    end: 20
匹配位于第 10 到 20 行之间的节点

仅开始行

rule:
  range:
    start: 100
匹配从第 100 行开始的所有节点

🔗 关系规则 >>>

基于周围节点过滤目标节点

inside - 在...内部

rule:
  pattern: await $PROMISE
  inside:
    kind: for_in_statement
    stopBy: end
匹配在 for_in_statement 内部的 await 表达式

has - 包含

rule:
  kind: pair
  has:
    field: key
    regex: 'prototype'
匹配包含特定 key 的 pair 节点

➡️ follows & precedes >>>

基于节点位置关系进行匹配

follows - 跟随

pattern: console.log('hello');
follows:
  pattern: console.log('world');
console.log('hello');  // 不匹配
console.log('world');
console.log('hello');  // 匹配!!

precedes - 前置

pattern: console.log('world');
precedes:
  pattern: console.log('hello');
匹配在特定节点之前的节点

🛑 stopBy 选项 >>>

控制关系规则的搜索范围

stopBy: end

has:
  stopBy: end
  pattern: $MY_PATTERN
搜索直到到达根节点、叶节点或首尾兄弟节点

stopBy: neighbor (默认)

has:
  stopBy: neighbor
  pattern: $MY_PATTERN
仅匹配直接子节点

stopBy: 自定义规则

inside:
  stopBy:
    kind: function
  pattern: function test($$$) { $$$ }
当遇到 function 节点时停止搜索

🔀 组合规则 >>>

使用逻辑运算符组合多个规则

any - 任意匹配

rule:
  pattern: await $PROMISE
  inside:
    any:
      - kind: for_in_statement
      - kind: for_statement
      - kind: while_statement
      - kind: do_statement
匹配在任意一种循环内部的 await 表达式

all - 全部匹配

rule:
  all:
    - pattern: console.log($$$)
    - inside:
        kind: function_declaration
同时满足所有条件的节点

❌ not 规则 >>>

排除匹配特定规则的节点

基本用法

rule:
  pattern: console.log($$$)
  not:
    inside:
      kind: function_declaration
匹配不在函数声明内部的 console.log

组合使用

rule:
  any:
    - pattern: console.log($$$)
    - pattern: console.error($$$)
  not:
    inside:
      kind: test_block
匹配 console.log 或 console.error,但不在测试块中

🎯 matches 规则 >>>

使用外部规则匹配节点

基本用法

rule:
  matches: my-rule-id
匹配由 my-rule-id 定义的规则

组合使用

rule:
  any:
    - matches: console-rule
    - matches: debug-rule
  not:
    inside:
      kind: test_block
复用已定义的规则进行组合匹配

🔧 实用规则 >>>

提供额外的实用功能

inside - 在...内部

rule:
  pattern: $A
  inside:
    pattern: function test($$$) { $$$ }
    stopBy:
      kind: function
查找在名为 test 的函数内部的节点

has - 包含

rule:
  kind: object
  has:
    kind: pair
    field: key
    regex: 'dangerous'
匹配包含特定键值对的对象

📝 编写规则技巧 >>>

编写高效准确的 ast-grep 规则的最佳实践

使用 pattern 对象解决歧义

pattern:
  selector: field_definition
  context: class A { $FIELD = $INIT }
当简单字符串模式无法解析时,提供上下文帮助解析器

选择合适的 strictness

pattern:
  strictness: smart  # 默认,跳过未命名节点
  # strictness: cst   # 最严格,匹配所有节点
  # strictness: ast   # 仅匹配命名节点
  # strictness: relaxed  # 忽略注释和未命名节点
  # strictness: signature  # 仅匹配节点类型
根据需求选择严格度级别

🎨 field 选项 >>>

指定节点的特定字段进行匹配

指定字段

kind: pair
has:
  field: key
  regex: 'prototype'
var a = {
  prototype: anotherObject  // 匹配
}

var a = {
  normalKey: prototype  // 不匹配
}
确保匹配特定字段的值,而非任意子节点

💡 高级用法 >>>

ast-grep 的高级功能和技巧

嵌套关系规则

rule:
  pattern: await $PROMISE
  inside:
    any:
      - kind: for_in_statement
      - kind: for_statement
    not:
      kind: try_statement
组合多个关系规则进行精确匹配

元变量在 fix 中使用

rule:
  pattern: console.log($MSG)
  fix: logger.info($MSG)
关系规则中捕获的元变量可在 fix 中使用