NodeJS处理Telegram历史文本:按规则提取交易信号数据
用Node.js逐行解析Telegram交易历史记录的实现方案
我来给你梳理下怎么实现这个需求,刚好我之前处理过类似的Telegram日志解析场景,咱们一步步来:
核心思路
咱们需要逐行遍历文本文件,通过正则匹配触发不同的处理逻辑,同时用状态变量跟踪当前是否处于交易数据收集阶段。具体分这几个关键点:
- 用
readline模块实现高效的逐行读取(适合大文件,避免一次性读入导致内存溢出) - 编写精准的正则表达式匹配目标模式,捕获交易对、交易所等关键信息
- 用状态变量管理数据收集的开始和结束(遇到当日时间戳时停止收集当前交易的内容)
具体实现步骤
1. 引入依赖并定义正则
首先我们需要Node.js内置的fs和readline模块,然后针对两个目标模式编写正则:
- 交易信号行正则:匹配
Free_Trade_Calls__AltSignals:XXX / XXX (exchange)格式,捕获交易对的两个币种和交易所 - 时间戳正则:假设你的时间戳格式是类似
[YYYY-MM-DD HH:MM:SS](如果格式不同,你可以直接调整这个正则) - TARGET模式正则:匹配
Free_Trade_Calls__AltSignals:TARGET
const fs = require('fs'); const readline = require('readline'); // 匹配交易信号行的正则,捕获币种1、币种2、交易所 const tradeSignalRegex = /^Free_Trade_Calls__AltSignals:([A-Z0-9]+) \/ ([A-Z0-9]+) \(([a-z]+)\)$/; // 匹配时间戳的正则(请根据你的实际格式调整) const timestampRegex = /^\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\]$/; // 匹配TARGET模式的正则 const targetSignalRegex = /^Free_Trade_Calls__AltSignals:TARGET$/;
2. 初始化状态变量
我们需要几个变量来跟踪当前的处理状态:
isCollecting:标记是否正在收集某条交易的后续内容currentTrade:存储当前交易的所有信息(交易对、交易所、后续行内容)allTrades:用来存储所有解析完成的交易数据(方便后续批量处理)
let isCollecting = false; let currentTrade = null; const allTrades = [];
3. 创建逐行读取接口并处理每行
用readline.createInterface创建读取器,然后监听line事件处理每一行:
const rl = readline.createInterface({ input: fs.createReadStream('telegram-history.txt'), // 替换成你的文件路径 crlfDelay: Infinity // 兼容所有换行符格式 }); rl.on('line', (line) => { // 先处理交易信号行 const tradeMatch = line.match(tradeSignalRegex); if (tradeMatch) { // 如果之前在收集其他交易,先把之前的存入allTrades if (isCollecting && currentTrade) { allTrades.push(currentTrade); } // 初始化当前交易 const [, base, quote, exchange] = tradeMatch; currentTrade = { pair: `${base}/${quote}`, exchange: exchange, details: [] }; isCollecting = true; return; } // 处理TARGET模式 const targetMatch = line.match(targetSignalRegex); if (targetMatch) { // 这里写你需要的TARGET模式处理逻辑,比如: console.log('触发TARGET模式处理'); // 例如可以标记当前交易的TARGET状态,或者执行特定操作 if (currentTrade) { currentTrade.hasTarget = true; } return; } // 如果正在收集交易内容 if (isCollecting && currentTrade) { // 检查是否遇到时间戳,如果是则结束收集 if (timestampRegex.test(line)) { allTrades.push(currentTrade); isCollecting = false; currentTrade = null; } else { // 否则把当前行加入交易详情(trim去首尾空格,可按需调整) currentTrade.details.push(line.trim()); } } }); // 文件读取完成后的收尾处理 rl.on('close', () => { // 处理最后一条未完成的交易(如果文件末尾没有时间戳) if (isCollecting && currentTrade) { allTrades.push(currentTrade); } // 这里可以对所有解析好的交易数据做后续处理,比如打印、存数据库等 console.log('解析完成,共获取到', allTrades.length, '条交易记录'); console.log('第一条交易示例:', JSON.stringify(allTrades[0], null, 2)); });
4. 关键细节说明
- 正则调整:如果你的时间戳格式不是
[YYYY-MM-DD HH:MM:SS],一定要修改timestampRegex的匹配规则,比如如果是YYYY/MM/DD HH:MM,就改成^\d{4}/\d{2}/\d{2} \d{2}:\d{2}$ - 数据结构扩展:
currentTrade的结构可以根据你的需求灵活调整,比如添加收集时间、TARGET相关字段等 - 大文件适配:
readline是流式处理,即使是几GB的Telegram历史文件也能轻松处理,不会占满内存
测试建议
你可以先拿一小段测试文本跑一下,比如:
[2024-05-20 10:00:00] Free_Trade_Calls__AltSignals:GAS / BTC (binance) Entry: 0.00001234 Stop Loss: 0.00001100 Take Profit 1: 0.00001500 [2024-05-20 10:05:00] Free_Trade_Calls__AltSignals:TARGET Free_Trade_Calls__AltSignals:RDN / BTC (bittrex) Entry: 0.00000456 [2024-05-20 10:10:00]
跑起来之后看看allTrades的输出是否符合预期,再根据实际情况调整正则和逻辑。
内容的提问来源于stack exchange,提问作者Roberto Balejík
相关产品推荐
相关产品推荐

