You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

正则表达式已包含感叹号匹配规则为何无法匹配带感叹号的兑换码

问题根因
  • 字符串转义错误:你通过字符串拼接生成正则表达式时,直接写的'\b'会被JavaScript解析为字符串中的退格转义字符,而非正则语法里的单词边界标识,要生成正则可用的\b需要写成'\\b'做两层转义。
  • 单词边界规则不适配场景:正则中的\b仅会匹配「单词字符(大小写字母、数字、下划线)」和「非单词字符」的交界,!属于非单词字符,如果兑换码以!开头或结尾,边界匹配会直接失败,哪怕你已经把!加到了字符匹配范围里也不会生效。
修复方案

把原生单词边界匹配替换为自定义边界规则,同时修正转义问题,另外给正则加上全局匹配修饰符,避免只匹配帖子里的第一个兑换码。

修复后完整代码
// 可直接在线运行
"use strict";

async function main() {
    let https = require('https')

    let url_search_loot = 'https://www.reddit.com/r/idlechampions/search.json?q=flair_name%3A%22loot%22&restrict_sr=1&sort=new'
    let code_one_letter_range = '0-9a-zA-Z!'

    let code_one_letter_rx = '[' + code_one_letter_range + ']'
    let code_one_letter_not_rx = '[^' + code_one_letter_range + ']'

    let patterns = [
        // 4组4位字符用-连接:XXXX-XXXX-XXXX-XXXX
        Array(4).fill(code_one_letter_rx + '{4}').join('-'),
        // 3组4位字符用-连接:XXXX-XXXX-XXXX
        Array(3).fill(code_one_letter_rx + '{4}').join('-'),
        // 无短横线16位字符
        code_one_letter_rx + '{16}',
        // 无短横线12位字符
        code_one_letter_rx + '{12}',
    ]
    // 替换原有的\b边界为自定义边界,匹配字符串开头/非允许字符作为起止边界
    const startBoundary = `(^|${code_one_letter_not_rx})`
    const endBoundary = `($|${code_one_letter_not_rx})`
    patterns.forEach((val, idx, array) => array[idx] = `${startBoundary}(${val})${endBoundary}`)
    // 加g修饰符全局匹配
    let all_patterns = RegExp(patterns.join('|'), 'g')

    function https_get_promise(url, resolve, reject) {
        return https.get(url_search_loot, (res) => {
            let data = '';

            res.on('data', (chunk) => data += chunk)

            res.on('end', () => {
                res.data = data
                resolve(res)
            })

        }).on('error', (err) => reject(err))
    }

    let request = new Promise((resolve, reject) => https_get_promise(url_search_loot, resolve, reject))
    let res = await request
    let res_obj = JSON.parse(res.data)

    let errors = []
    res_obj.data.children.forEach((post, idx) => {
        let matches = [...post.data.selftext.matchAll(all_patterns)]
        if (!matches || matches.length === 0) {
            errors.push(post)
        } else {
            // 提取匹配到的兑换码,跳过前后边界的捕获组
            matches.forEach(match => {
                const code = match.slice(2).find(v => v != null)
                console.log(code)
            })
        }
    })

    if (errors.length > 0) {
        console.log("\n\n\n=== Errors ===")
        for (const post of errors) {
            console.log(post.data.selftext)
            console.log('======')
        }
    }
}

main()

内容的提问来源于stack exchange,提问作者Rocket J

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 06:15:04