Matching multiline input with RegExp and grouping matches from consecutive lines

Imagine having a text file with the following content:

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

The objective is to extract the values of k1 and k2 while keeping them grouped together. For instance, the first match should return 123 and 456 as a pair, the second match should return 789 and 101, and 121 and 141 for the third match.

I can create a regex pattern to get each line individually or even capture all relevant lines in the file, but I'm struggling to figure out how to maintain these matches in groups.

The challenge lies in the varying number of AAAA lines between groups - it could be one line, then some different lines, followed by four AAAA lines, and so on.

EDIT -- To clarify, the distinct values from each group must be kept separate.

In the case where there's only one AAAA line within a group, I expect the values 123 and 456.

If there are two AAAA lines in a group, like in the second set, I need to retrieve 789, 101, 121, and 141. Furthermore, it's crucial to distinguish that 789 and 101 belong together (from one line) and 121 and 141 form another pair within the same group, completely separate from the 123 and 456 values.

Ultimately, I aim to convert this data into JavaScript objects, such as:

{ '123': '456'}

and

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

If there were 15 consecutive AAAA lines, the resulting object would contain 15 key-value pairs.

Answer №1

Here are some steps you can take:

Below is a live-demo showcasing the proof of concept:

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%;}

Answer №2

If you're looking to efficiently extract specific data from a text, consider using a two-step approach with regular expressions. The first regex pattern locates and groups lines that start with "AAAA " followed by one or more spaces, while the second regex captures the values of "k1" and "k2."

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 );

Answer №3

Apologies for my brevity as I am typing from a mobile device.

function decipherText(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
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How can one effectively develop a component library that is compatible with both React and Preact?

I'm currently in the midst of a project that involves both React and Preact. I've come across a situation where I need to utilize the same component for both React and Preact. Would it be wise to package the component into an npm library? What a ...

How do I create a generic function in TypeScript that adjusts its behavior based on the input argument?

Is there a way to create a generic function that can accept generic arguments like Data<string, number>? Take a look at this code snippet: interface Data<T,R> { a:T; c:R; } function foo( data: Data<string, number> ){ return t ...

NodeJS closes the previous server port before establishing a new server connection

During my development and testing process, whenever I make changes, I find myself having to exit the server, implement the updates, and then start a new server. The first time I run the command node server.js, everything works perfectly. However, when I m ...

Google Script: How to automatically open a newly created text document after its creation

I decided to try out this script for generating Google text documents from Google Spreadsheet data. However, I noticed that the new text document created from a template is always placed in the default folder. This means that I have to manually locate the ...

What is the best approach to animating a specified quantity of divs with CSS and javascript?

How neat is this code snippet: <div class="container"> <div class="box fade-in one"> look at me fade in </div> <div class="box fade-in two"> Oh hi! i can fade too! </div> <div class="box fade-in three"& ...

Having trouble modifying a value in a form and submitting it to the following jsp page

I'm encountering an issue with changing the value in a hidden input element before submitting data to another JSP file (db.jsp) for processing. The value should be different depending on which button is clicked, but it always remains as the default va ...

What is the best way to programmatically change the event tied to an element's click

<div id="filters"></div> <div id="available"> <span class="badge badge-pill" onclick="addFilter()">Label</span> </div> function addFilter(event) { document.getElementById("filters").appendChild(eve ...

Clearing hoverIntent using jQuery

In my scenario, I have three items identified as X, Y, and Z. The functionality of hovering is controlled by the hoverIntent. When I hover on item X, a tooltip is displayed using the following code: jQuery('.tooltiper').hoverIntent({ ove ...

Discovering the geometric boundaries of a body of text

Seeking help with determining the geometric bounds of text inside hyperlinks in an InDesign document. I've tried to do this using ExtendScript but haven't had any luck. // Loop through and export hyperlinks in the document for (k = 0; k < myD ...

Protractor's count() function fails to execute properly when called outside of a promise loop

var alerts = element.all(by.xpath("//div[@class='notification-content']")); alerts.count().then(function (val) { console.log(val); }); let compareValue = val; Is there a way to access the 'value' outside of the promise l ...

ReactJS with conditional closing tags

Here is a sample json response : {id: 1, name: a} {id: 2, name: b} {id: 3, name: c} {id: 4, name: d} {id: 5, name: e} {id: 6, name: f} I am looking to organize these by pairs in my React component like so : <div className="group-item"> ...

Guide on retrieving the initial value from a map in a React application

In my React project, I am working with a map that has string keys and values. Here's an example: let map = new Map(); map.set("foo", "bar"); map.set("foo-bar", "bar-foo"); What is the best way to retrieve the first value from this map? ...

gulp-uglify is responsible for the malfunction of the constructor.name property

When I make a change in my gulpfile.js by commenting out the line .pipe(uglify({ preserveComments: 'some'})) my code appears neat and tidy, and the next line functions correctly: if(Mystudy.constructor.name != "MyStudyView") However, ...

`How can I effectively test a React.js page utilizing both Context and useEffect?`

I'm struggling with testing a page that uses Context and useEffect with Jest and Testing-library, can you offer any assistance? REPOSITORY: https://github.com/jefferson1104/padawan Context File: src/context/personContext.tsx import { createContext, ...

Learn how to automatically populate input fields based on the values entered in previous fields. These dynamic fields are generated based on the user

In the following code snippet, fields are dynamically created using jQuery... For more visual explanation, refer to this image: The goal is to calculate the grand total based on previous inputs and display the result when an onclick() event occurs. < ...

Guide to verify the user selection within a select form

Here is a form with a select field: <form method="post" name="posting_txt" onSubmit="return blank_post_check();" id="post_txt"> <select style="background: transparent; border-bottom:5px;" name="subname" class="required"> ...

Choose an image to be displayed at either full width or full height, depending on which dimension is reached first

I have a query regarding resizing an image within a div to either 100% width or 100% height of the containing div. Despite setting max-height and max-width to 100% as recommended here, I still encounter overflow issues without wanting to crop the image usi ...

Is there a way to circumvent the eg header along with its contents and HTML code using JavaScript?

I have a script in JavaScript that is designed to replace the content of data-src attribute within each img tag with src. However, I am facing an issue where this script interferes with the functionality of a slider located in the header section. The sli ...

A guide on adding two fields together in AngularJS and displaying the output in a label

I am facing a unique issue on my webpage. Including two inputs and a label in the page, I want the label to display the sum of the values entered into these two inputs. My initial attempt was as follows: Sub-Total <input type="text" ng-model="Propert ...

Guide to modify target blank setting in Internet Explorer 8

<a href="brochure.pdf" target="_blank" >Click here to download the brochure as a PDF file</a> Unfortunately, using 'target blank' to open links in a new tab is not supported in Internet Explorer 8. Are there any alternative solutio ...