【问题标题】:RegExp match multiline input and group matches from adjacent lines [duplicate]RegExp匹配多行输入和来自相邻行的组匹配[重复]
【发布时间】:2020-05-04 19:43:37
【问题描述】:

假设我在文件中有一些文本

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 行只有一行,所以我期望值123456

第二组AAAA 行有2 行,所以我需要789101121141 的值。此外,我需要知道789101 是相关联的(来自同一行),121141 是相关联的(来自同一行),但仍然是第二个的所有部分组(与123456 没有任何关联)

最终我想访问对象(javascript),例如

{ '123': '456'}

 {
    '789': '101',
    '121': '141
 }

如果一行中有 15 行 AAAA 行,则该对象将有 15 个键值对。

【问题讨论】:

  • /^AAAA k1="(\d+)" k2="(\d+)"$/gm 这对您有什么帮助?我不完全确定我理解你的问题。
  • @anubhava 不会将分组保持在一起
  • @hackape 不会将跨行分组保持在一起。关键是AAAA 行成组出现,可能有 1 个这样的行,可能有 4 个这样的行,并且需要将值保持在一起。
  • @anubhava 我需要将123456 值与789 和后续值分开
  • @anubhava,已编辑,希望更清晰

标签: javascript regex typescript


【解决方案1】:

您可以执行以下操作:

您可以在下面找到概念验证现场演示:

const src = `AAAA k1="123" k2="456"
            several lines of other stuff
            AAAA k1="789" k2="101"
            AAAA k1="121" k2="141"`,

      result = src
        .split("\n")
        .map(line => {
          const matches = line.match(/AAAA k1=\"(\d+)\" k2=\"(\d+)\"/)
          return matches ? {[matches[1]]:matches[2]} : null
        })
        .reduce((r,o,i,s) => 
          (o && (!i || !s[i-1]) ? r.push(o) : Object.assign(r[r.length-1], o), r), [])
        
      
console.log(result)
.as-console-wrapper{min-height:100%;}

【讨论】:

    【解决方案2】:

    您可以使用这种两阶段方法。第一个正则表达式是捕获所有以AAAA\s+ 开头的行并将它们组合在一起,第二个正则表达式抓取k1k2 值:

    const re1 = /(?:^AAAA\s+.*\n?)+/gm;
    const re2 = /\s+k1="([^"]+)"\s+k2="([^"]+)"/g;
    
    const str = `AAAA k1="123" k2="456"
    several lines of other stuff
    AAAA k1="789" k2="101"
    AAAA k1="121" k2="141"`;
    let m1;
    let m2;
    let result = [];
    
    while ((m1 = re1.exec(str)) !== null) {
      var grpMap = {};
      while ((m2 = re2.exec(m1[0])) !== null)
        grpMap[m2[1]] = m2[2]
      result.push( grpMap );
    }
    
    console.log( result );

    【讨论】:

      【解决方案3】:

      在手机上打字,请原谅我太简洁了。

      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
      }
      

      【讨论】:

        猜你喜欢
        • 2021-12-01
        • 1970-01-01
        • 2016-05-20
        • 2018-05-07
        • 2012-03-07
        • 2017-07-11
        • 1970-01-01
        • 1970-01-01
        • 2013-03-15
        相关资源
        最近更新 更多