Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/465.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript RegExp匹配来自相邻行的多行输入和组匹配_Javascript_Regex_Typescript - Fatal编程技术网

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
}