如何使用正则表达式提取指定前后关键词范围内按序排列的匹配数值
解决方案
实现思路
你需要的是从首个after关键词出现的位置开始,按before数组的优先级依次切割文本段,提取每段内所有符合要求的数值,具体逻辑如下:
- 先定位首个
after关键词在文本中的起始位置,只处理该位置之后的文本 - 遍历
before数组,依次按每个非空关键词切割当前待处理文本:- 若当前
before关键词存在,提取该关键词之前的文本里的所有符合要求的数值 - 切割后剩余的文本(该关键词之后的内容)进入下一轮处理
- 若当前
- 若遍历到
before中的空值,或者before数组遍历完仍有剩余文本,直接提取剩余文本里的所有符合要求的数值 - 所有提取到的数值按出现顺序返回即可
代码实现(JavaScript 示例)
首先写通用的转义正则特殊字符的工具函数,避免关键词含正则符号报错:
function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); }
核心提取函数:
function extractValues(text, afterArr, beforeArr) { // 匹配数值的正则,若仅需要匹配value (不含valueTwo、valueThree等变体),删掉\w*即可 const valueReg = /\bvalue\w*\s(\d+(?:[.,]\d+)?)/g; const result = []; // 定位首个after关键词的位置 const afterJoin = afterArr.filter(Boolean).map(v => escapeRegExp(v.trim())).join('|'); if (!afterJoin) return result; const afterMatch = text.match(new RegExp(afterJoin)); if (!afterMatch) return result; let remainingText = text.slice(afterMatch.index + afterMatch[0].length); // 按before数组依次切割提取 for (const beforeItem of beforeArr) { const beforeKey = beforeItem.trim(); // 遇到空值直接提取剩余所有文本的数值 if (!beforeKey) { let match; while ((match = valueReg.exec(remainingText)) !== null) { result.push(match[1]); } remainingText = ''; break; } // 匹配当前before关键词的位置 const beforeReg = new RegExp(escapeRegExp(beforeKey)); const beforeMatch = remainingText.match(beforeReg); if (beforeMatch) { // 提取当前关键词之前的数值 const segment = remainingText.slice(0, beforeMatch.index); let match; valueReg.lastIndex = 0; while ((match = valueReg.exec(segment)) !== null) { result.push(match[1]); } // 更新剩余文本为当前关键词之后的内容 remainingText = remainingText.slice(beforeMatch.index + beforeMatch[0].length); } } // 处理未遍历完的剩余文本 if (remainingText) { let match; valueReg.lastIndex = 0; while ((match = valueReg.exec(remainingText)) !== null) { result.push(match[1]); } } return result; }
测试验证
用你给出的测试文本验证:
const testText = "xxxx yyyy yyy xxx start value 123.5 yxyxyxyxy beginning valueTwo 156.56 yxyxyxy xyxyxy end yxyxyxy valueThree 6678.56 yxyxyxyxy xyxyx finish"; // 规则1测试:after = ["start"], before = ["end"] console.log(extractValues(testText, ["start"], ["end"])); // 输出 ["123.5", "156.56"] // 规则2测试:after = ["start"], before = ["end", "finish"] console.log(extractValues(testText, ["start"], ["end", "finish"])); // 输出 ["123.5", "156.56", "6678.56"] // 规则3测试:after = ["start"], before = ["ABC", "finish"] console.log(extractValues(testText, ["start"], ["ABC", "finish"])); // 输出 ["123.5", "156.56", "6678.56"] // 规则4测试:after = ["start"], before = ["end", ""] console.log(extractValues(testText, ["start"], ["end", ""])); // 输出 ["123.5", "156.56", "6678.56"]
所有测试结果完全符合规则要求。
内容的提问来源于stack exchange,提问作者Oksana Ok
相关产品推荐
相关产品推荐

