Javascript RegExp匹配来自相邻行的多行输入和组匹配
假设我在一个文件中有一些文本Javascript RegExp匹配来自相邻行的多行输入和组匹配,javascript,regex,typescript,Javascript,Regex,Typescript,假设我在一个文件中有一些文本 AAAA k1="123" k2="456" several lines of other stuff AAAA k1="789" k2="101" AAAA k1="121" k2="141" 目标是捕获k1和k2值,但将分组保持在一起。因此,第一场比赛将以123和456的成绩分组,第二场比赛将以789和101,121和141的成绩分组 我可以编写正则表达式来获取任何一行,甚至匹配文件中的所有相关行,但我不知道如何将匹配项分组保存 最困难的是,以AAAA开头的行
AAAA k1="123" k2="456"
several lines of other stuff
AAAA k1="789" k2="101"
AAAA k1="121" k2="141"
目标是捕获k1和k2值,但将分组保持在一起。因此,第一场比赛将以123和456的成绩分组,第二场比赛将以789和101,121和141的成绩分组
我可以编写正则表达式来获取任何一行,甚至匹配文件中的所有相关行,但我不知道如何将匹配项分组保存
最困难的是,以AAAA开头的行数在组中不是恒定的,例如,可能是1条AAAA行,然后是一些其他行,然后是4条AAAA行,依此类推
编辑——确定澄清一下,不同的值需要按组分开
因此,第一组AAAA
行只有一行,因此我希望值123
和456
第二组AAAA
行有两行,因此我需要值789
,101
,121
,和141
。此外,我需要知道789
和101
是关联的(来自同一行),121
和141
是关联的(来自同一行),但仍然是第二组的所有部分(与123
和456
没有任何关联)
最终,我希望访问对象(javascript),例如
及
如果一行中有15行AAAA,那么该对象将有15个键值对。在移动电话上键入,请原谅我的简短
function magic(text) {
const lines = text.split("\n")
const re = /^AAAA k1="(\d+)" k2="(\d+)"$/
const lastIndex = lines.length - 1
return lines.reduce((acc, line, index) => {
const matched = line.match(re)
if (matched) {
if (!acc.current) acc.current = {}
acc.current[matched[1]] = matched[2]
}
if (!matched || index == lastIndex) {
if (acc.current) {
acc.final.push(acc.current)
acc.current = null
}
}
return acc
}, { current: null, final: [] }).final
}
您可以使用此两阶段方法。第一个正则表达式捕获以
AAAA\s+
开头的所有行并将它们分组,第二个正则表达式获取k1
和k2
值:
const re1=/(?:^AAAA\s+.*\n?)+/gm;
常量re2=/\s+k1=“([^”]+)”\s+k2=“([^”]+)”/g;
const str=`AAAA k1=“123”k2=“456”
几行其他的东西
AAAA k1=“789”k2=“101”
AAAA k1=“121”k2=“141”`;
让m1;
让m2;
让结果=[];
while((m1=re1.exec(str))!==null){
var grpMap={};
while((m2=re2.exec(m1[0])!==null)
grpMap[m2[1]]=m2[2]
结果:推送(grpMap);
}
控制台日志(结果)代码>您可以执行以下操作:
- 将多行输入到行字符串数组中
- 将每行转换为格式为
{k1:k2}
或null(如果未找到匹配项)的对象
- 将consequentive匹配(例如with)组合到单个对象中
您可以在下面找到概念验证现场演示:
const src=`AAAA k1=“123”k2=“456”
几行其他的东西
AAAA k1=“789”k2=“101”
AAAA k1=“121”k2=“141”`,
结果=src
.split(“\n”)
.map(行=>{
常量匹配=行。匹配(/AAAA k1=\“(\d+)\”k2=\“(\d+)\”/)
返回匹配项?{[匹配项[1]]:匹配项[2]}:null
})
.减少((r,o,i,s)=>
(o&(!i | |!s[i-1])?r.push(o):Object.assign(r[r.length-1],o),r),[])
console.log(结果)
.as控制台包装{min height:100%;}
/^AAAA k1=“(\d+”k2=“(\d+)”$/gm
这对您有什么好处?我不完全确定我是否理解你的问题。@anubhava,这不会保留分组together@hackape这并不能使跨线分组保持在一起。关键的一点是,AAAA
行是成组的,可能有1行,可能有4行,需要将这些值放在一起。@anubhava我需要将123
和456
值与789
和子序列分开values@anubhava,编辑,希望更清晰
{
'789': '101',
'121': '141
}
function magic(text) {
const lines = text.split("\n")
const re = /^AAAA k1="(\d+)" k2="(\d+)"$/
const lastIndex = lines.length - 1
return lines.reduce((acc, line, index) => {
const matched = line.match(re)
if (matched) {
if (!acc.current) acc.current = {}
acc.current[matched[1]] = matched[2]
}
if (!matched || index == lastIndex) {
if (acc.current) {
acc.final.push(acc.current)
acc.current = null
}
}
return acc
}, { current: null, final: [] }).final
}