app.regex - 正则表达式 API

正则表达式匹配和替换。基于 NSRegularExpression 实现。

匹配方法

app.regex.match(str, pattern, options?)

获取第一个匹配及其捕获组。

参数:

  • str (string) - 要匹配的字符串
  • pattern (string) - 正则表达式模式
  • options (table, 可选):
    • ignoreCase (boolean) - 忽略大小写
    • multiline (boolean) - 多行模式(^ 和 $ 匹配行首行尾)
    • dotMatchesLineSeparators (boolean) - 点号匹配换行符

返回值: table|nil - 匹配结果或 nil

-- 简单匹配
local m = app.regex.match("hello world", "\\w+")
-- { match = "hello", start = 0, ["end"] = 5 }

-- 带捕获组
local m = app.regex.match("hello world", "(\\w+) (\\w+)")
-- {
--     match = "hello world",
--     start = 0,
--     ["end"] = 11,
--     groups = {"hello", "world"}
-- }

-- 忽略大小写
local m = app.regex.match("Hello", "hello", {ignoreCase = true})

app.regex.matchAll(str, pattern, options?)

获取所有匹配。

参数: 同 match

返回值: array - 匹配结果数组

local matches = app.regex.matchAll("a1b2c3", "\\d")
-- {
--     { match = "1", start = 1, ["end"] = 2 },
--     { match = "2", start = 3, ["end"] = 4 },
--     { match = "3", start = 5, ["end"] = 6 }
-- }

app.regex.test(str, pattern, options?)

测试是否匹配。

参数: 同 match

返回值: boolean

app.regex.test("hello@example.com", "^[\\w.-]+@[\\w.-]+\\.\\w+$")  -- true
app.regex.test("invalid-email", "^[\\w.-]+@[\\w.-]+\\.\\w+$")      -- false

提取方法

app.regex.find(str, pattern, options?)

返回第一个匹配的字符串。

参数: 同 match

返回值: string|nil - 匹配的字符串或 nil

local word = app.regex.find("hello world", "\\w+")
-- "hello"

app.regex.findAll(str, pattern, options?)

返回所有匹配的字符串。

参数: 同 match

返回值: array - 字符串数组

local numbers = app.regex.findAll("a1b2c3", "\\d")
-- {"1", "2", "3"}

local words = app.regex.findAll("hello world", "\\w+")
-- {"hello", "world"}

app.regex.groups(str, pattern, options?)

返回第一个匹配的捕获组。

参数: 同 match

返回值: array|nil - 捕获组数组或 nil

local groups = app.regex.groups("hello world", "(\\w+) (\\w+)")
-- {"hello", "world"}

local parts = app.regex.groups("2024-01-15", "(\\d{4})-(\\d{2})-(\\d{2})")
-- {"2024", "01", "15"}

替换方法

app.regex.replace(str, pattern, replacement, options?)

替换第一个匹配。

参数:

  • str (string) - 原字符串
  • pattern (string) - 正则表达式模式
  • replacement (string) - 替换内容(支持 \(1, \)2 等反向引用)
  • options (table, 可选): 同 match

返回值: string - 替换后的字符串

-- 替换第一个数字
app.regex.replace("a1b2c3", "\\d", "X")  -- "aXb2c3"

-- 使用反向引用
app.regex.replace("hello world", "(\\w+)", "[$1]")  -- "[hello] world"

app.regex.replaceAll(str, pattern, replacement, options?)

替换所有匹配。

参数: 同 replace

返回值: string - 替换后的字符串

-- 替换所有数字
app.regex.replaceAll("a1b2c3", "\\d", "X")  -- "aXbXcX"

-- 替换所有空白为下划线
app.regex.replaceAll("hello world", "\\s+", "_")  -- "hello_world"

-- 使用反向引用
app.regex.replaceAll("hello world", "(\\w+)", "[$1]")  -- "[hello] [world]"

分割方法

app.regex.split(str, pattern, options?)

按正则分割字符串。

参数:

  • str (string) - 要分割的字符串
  • pattern (string) - 分隔符模式
  • options (table, 可选): 同 match

返回值: array - 分割后的数组

app.regex.split("a1b2c3", "\\d")           -- {"a", "b", "c", ""}
app.regex.split("a  b   c", "\\s+")        -- {"a", "b", "c"}
app.regex.split("one,two;three", "[,;]")   -- {"one", "two", "three"}

选项说明

选项 说明
ignoreCase 忽略大小写匹配
multiline 多行模式,^$ 匹配每行的开头和结尾
dotMatchesLineSeparators . 可以匹配换行符

常用模式

-- 邮箱
local EMAIL = "^[\\w.-]+@[\\w.-]+\\.\\w+$"

-- URL
local URL = "^https?://[\\w.-]+(?:/[\\w./-]*)?$"

-- IP 地址
local IP = "^(?:\\d{1,3}\\.){3}\\d{1,3}$"

-- 日期(YYYY-MM-DD)
local DATE = "^\\d{4}-\\d{2}-\\d{2}$"

-- 十六进制颜色
local HEX_COLOR = "^#?[0-9A-Fa-f]{6}$"

-- 文件扩展名
local FILE_EXT = "\\.(\\w+)$"

示例

提取文件名中的数字

function MyPlugin:handleExtractNumbers(context)
    local results = {}

    for _, file in ipairs(context.selectedFiles) do
        local name = app.path.basename(file)
        local numbers = app.regex.findAll(name, "\\d+")

        if #numbers > 0 then
            table.insert(results, name .. ": " .. table.concat(numbers, ", "))
        end
    end

    if #results > 0 then
        app.dialog.alert({
            title = "提取结果",
            message = table.concat(results, "\n")
        })
    else
        app.dialog.alert({title = "提示", message = "未找到数字"})
    end
end

批量重命名(正则替换)

function MyPlugin:handleRegexRename(context)
    local result = app.dialog.form({
        title = "正则重命名",
        fields = {
            {type = "text", id = "pattern", label = "匹配模式", default = ""},
            {type = "text", id = "replacement", label = "替换为", default = ""},
            {type = "checkbox", id = "ignoreCase", label = "忽略大小写", default = false}
        }
    })

    if not result or result.pattern == "" then return end

    -- 验证正则(尝试匹配空字符串)
    local valid = app.regex.test("", result.pattern) ~= nil or app.regex.test("test", result.pattern) ~= nil

    local renamed = 0
    for _, file in ipairs(context.selectedFiles) do
        local name = app.path.basename(file)
        local newName = app.regex.replaceAll(name, result.pattern, result.replacement, {
            ignoreCase = result.ignoreCase
        })

        if newName ~= name then
            local newPath = app.path.join(app.path.dirname(file), newName)
            if app.file.move(file, newPath) then
                renamed = renamed + 1
            end
        end
    end

    app.notification.show("完成", "重命名了 " .. renamed .. " 个文件")
end

验证文件名格式

function MyPlugin:validateFilenames(context)
    -- 验证格式:YYYY-MM-DD_description.ext
    local pattern = "^\\d{4}-\\d{2}-\\d{2}_[\\w-]+\\.\\w+$"

    local invalid = {}
    for _, file in ipairs(context.selectedFiles) do
        local name = app.path.basename(file)
        if not app.regex.test(name, pattern) then
            table.insert(invalid, name)
        end
    end

    if #invalid == 0 then
        app.dialog.alert({title = "验证通过", message = "所有文件名格式正确"})
    else
        app.dialog.alert({
            title = "格式错误",
            message = "以下文件名不符合格式:\n" .. table.concat(invalid, "\n")
        })
    end
end

解析日志文件

function MyPlugin:parseLogLine(line)
    -- 日志格式: [2024-01-15 10:30:45] [INFO] Message here
    local pattern = "^\\[(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2})\\] \\[(\\w+)\\] (.+)$"
    local groups = app.regex.groups(line, pattern)

    if groups then
        return {
            timestamp = groups[1],
            level = groups[2],
            message = groups[3]
        }
    end
    return nil
end
开发者文档
使用帮助
使用说明 脚本菜单 常见问题
脚本开发
开发指南
插件开发
快速开始 开发指南 示例插件
API 参考
概览 API 查询 插件信息 日志 Finder 上下文 插件设置 国际化
UI 与交互
对话框 进度条 系统通知 选择器 WebView 状态栏 Dock
文件与路径
文件操作 路径工具 Finder 操作 废纸篓 扩展属性 元数据 文件监听
数据格式
JSON Plist CSV XML PDF 图片
文本与编码
字符串 正则表达式 日期时间 颜色 加密编码
系统
Shell 命令 进程管理 应用管理 系统信息 AppleScript 快捷指令
系统信息
网络信息 电源/电池 屏幕/外观 音频控制 蓝牙设备 位置服务
网络
HTTP 请求 WebSocket URL 工具
输入与剪贴板
键盘模拟 鼠标模拟 全局热键 剪贴板 窗口管理
存储
SQLite Keychain UserDefaults
媒体
文字识别 二维码
工具
归档 类型标识 分享 定时器 防休眠 并发/协程