Create a structure of connected nodes by parsing a plain text string

My input is a string with annotations and data:

 var string = "@anno1[ data1 xyz @anno2[data2  @anno3[data3] data4] data5 @anno4[data6] data7]"

I want to transform this string into an object with structured information:

var childs = [ 
        {
            name : '@anno1',
            text : 'data1 xyz data2 data3 data4 data5 data6 data7',
        }, 
        {
            name : '@anno2',
            text : 'data2 data3 data4'
        }, 
        {
            name : '@anno3',
            text : 'data3'
        }, 
        {
            name : '@anno4',
            text : 'data6'
        } 
]

I have attempted various methods but so far, none have been successful. Any help would be greatly appreciated.

Below is the Java code I have tried utilizing:

    import java.util.HashMap;
import java.util.Map;

public class ExpressionTree {

    static Map <String, String> resultMap = new HashMap<String, String>(16);

    public static void main(String args[]) {
        // String exp = "[data1 xyz @anno2[data2 @anno3[data3] data4] data5 @anno4[data6] data7]";
        
        String exp = "@anno1[ data1 xyz @anno2[data2  @anno3[data3] data4] data5 @anno4[data6] data7 ]";

        parseRecursively(exp);
    }

    private static void parseRecursively(String exp) {

        String annotation = null;
        String annotationValue = null;

        if (exp.startsWith("@")) {
            int dataStartIndex = exp.indexOf("[");
            annotation = exp.substring(0, dataStartIndex);
            annotationValue = exp.substring(0 + dataStartIndex, exp.lastIndexOf("]")+1).trim();

            System.out.println(annotation);
            System.out.println(annotationValue);

            resultMap.put(annotation, annotationValue);

            parseRecursively(annotationValue);

        } else {
            int annotationStartIndex = exp.indexOf("@");
            int dataStartIndex = exp.substring(1).indexOf("[");

            if( -1 != annotationStartIndex || -1 != dataStartIndex)
            {
                annotation = exp.substring(annotationStartIndex, dataStartIndex+1).trim();

                String nextData = exp.substring(0 + dataStartIndex + 1).trim();
                String tmpNextData = nextData;

                int countOfOpenBrackets = 0;
                for (int i = 0; tmpNextData.charAt(i) != ']'; i++) {
                    // System.out.println(tmpNextData.charAt(i));
                    if (tmpNextData.charAt(i) == '[') {
                        countOfOpenBrackets++;
                    }
                    // tmpNextData = tmpNextData.substring(1);
                }

                tmpNextData = nextData;
                int endIndexOfCurrentData = 0;

                for (int i = 0; i < tmpNextData.length() && endIndexOfCurrentData == 0; i++) {
                    // System.out.println(tmpNextData.charAt(i));
                    if (tmpNextData.charAt(i) == ']') {
                        countOfOpenBrackets--;
                    }
                    if (countOfOpenBrackets == 0) {
                        endIndexOfCurrentData = i + 1;
                    }
                    // tmpNextData = tmpNextData.substring(1);
                }

                annotationValue = nextData.substring(0, endIndexOfCurrentData).trim();

                System.out.println(annotation);
                System.out.println(annotationValue);

                resultMap.put(annotation, annotationValue);

                parseRecursively(annotationValue);
            }
        }
        System.out.println(resultMap);
    }
}

Answer №1

Check out this JavaScript (ES6) solution:

function convertStringToObject(input) {
    "use strict";
    const tokens = input.match(/[\[\]]|[^\s\[\]]+/g),
        result = [];
    let index = 0;
    function parse() {
        const words = [];
        let obj;
        while (index < tokens.length) {
            let token = tokens[index];
            if (token[0] === '@') {
                obj = {name: token};
                result.push(obj);
            } else if (token === '[') {
                index++;
                obj.text = parse();
                words.push(obj.text);
            } else if (token === ']') {
                break;
            } else {
                words.push(token);
            }
            index++;
        }
        return words.join(' ');
    }
    parse();
    return result;
}

const inputString = "@anno1[ data1 xyz @anno2[data2  @anno3[data3] data4] data5 @anno4[data6] data7]";
const outputResult = convertStringToObject(inputString);
console.log(outputResult);
.as-console-wrapper { max-height: 100% !important; top: 0; }

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

What could be the reason behind the success of my API call in Chrome while encountering failure when implemented in my

I'm attempting to access the Binance API in order to obtain the current price of Litecoin (LTC) in Bitcoin (BTC). For this purpose, I have tested the following URL on my web browser: "https://api.binance.com/api/v1/ticker/price?symbol=LTCBTC". Now, I ...

Can you pinpoint the issue with this asynchronous function in Vue3?

Dealing with a simple concept error, I find myself unable to solve it. Within the onMounted hook, everything looks correct - an Array of three objects is displayed. However, when I return it to the template and try to interpolate it, all I see is an empty ...

Modifying the geometry of a plane in Three.js

Currently working on a simple terrain editor. When the mouse is clicked, I want the selected face to move up. The intersection is functioning well, and I am attempting to adjust the geometry in this manner: var intersects2 = ray.intersectObjects([ ...

Exploring the power of Knockout Js and Typeahead libraries

https://i.stack.imgur.com/38iZc.png Hello experts in Knockout and typeahead, I am receiving suggestions from the typeahead js as shown above. I have my data supplied in an array format var itemsRandom= ['Apple', 'Ball','Ape&apos ...

Instead of using <div>, try substituting it with a different HTML page

Seeking assistance on an HTML page project that involves jQuery, CSS, and HTML without server-side integration. Encountering an issue when attempting to replace a <div> with content from another HTML file saved on my computer. The main page code sni ...

Disable a href link using Jquery after it has been clicked, then re-enable it after a

There are several <a target="_blank"> links on my website that trigger API calls. I want to prevent users from double clicking on these buttons. This is what I have tried: .disable { pointer-events: none; } $(document).ready(function(e) { ...

Having trouble with the JQuery class selector?

Having a bit of trouble trying to select an element based on its class using $(".class"), and I can't seem to figure out why it's not working. So, the deal is - I have this image element that should appear when a function gets triggered: $("#co ...

Accessing the path to an imported file in Node.js

Currently, I am working on a parser and encountering imports such as ../modules/greeting.js. Additionally, I have an absolute path to the file from where I performed the import: C:\Desktop\Folder\src\scripts\main.js. I am seeking ...

Mastering the art of curating the perfect image for your Facebook timeline

Controlling the Like image presented on Facebook timeline can be done using the header element. In my single-page app, I have multiple like buttons, each should be connected to a different image. What is the best way to associate a specific image with e ...

What are the best practices for establishing a secure SignalR client connection?

While tackling this issue may not be solely related to SignalR, it's more about approaching it in the most efficient way. In C#, creating a singleton of a shared object is achievable by making it static and utilizing a lock to prevent multiple threads ...

Mapping JSON data with an elastic search cluster can be challenging, especially when dealing with a dynamic number of fields

I am currently developing an application where I need to map JSON data for storage in Elasticsearch. The challenge is that the number of fields in the JSON data is dynamic. How can I handle mapping in this scenario? Mapping Snippet var fs = uploadedFiles ...

Having trouble getting Firestore/Firebase to work with Next.js?

Hey everyone, I could really use some help here. I've been working on integrating Firebase into my Next.js app for the API. Everything works well when I build and run locally, but once I deploy to Vercel for production, I encounter a 500 - Internal S ...

Transferring data between functional components in ReactJS and dealing with the output of [object Object] or undefined

I'm struggling with passing a prop in functional components that are both located in the same .js file. I previously attempted to seek help for this issue, but unfortunately, it wasn't productive. My goal is to extract the member_id from the GET ...

Issue with Angular translation when utilizing a dynamic key variable

I am currently developing a project with Angular Js and incorporating the Angular-translate module In a specific scenario, I encountered an issue where the translation key needed to be stored as a variable. To address this, I created an object within the ...

jQuery ceases to function once AJAX content is loaded

Exploring Options for Flexible Data Display I'm currently in the process of building a webpage that allows users to choose between different layouts for loading data. This includes the option to display data in either a list format or a card interfac ...

Utilizing JavaScript in Protractor, explore a list to identify the selected checkboxes and those that remain unchecked

Currently, I am working on developing an end-to-end test using Protractor. My main objective is to extract the names from a list and then determine which checkboxes have been selected and which ones haven't. To check the state of the checkbox, I pla ...

Ways to add a prefix to every JSON response in play2 to avoid JSONP vulnerability from potential malicious requests

I'm looking to add a sequence of quotes ("')]}',\n") to all my JSON responses in order to enhance security and prevent JSONP escalation vulnerabilities. Does anyone know how this can be achieved within the play2 framework? I have curre ...

In Safari, there seems to be an issue where multiple URLs are not opening when clicked on from an anchor

Is there a way to open multiple URLs in Safari with just one click using window.open? I tried it, but only one URL opens in a new tab while the others do not. The version of Safari I am using is 11.0.1. onclick="window.open('URL1','_blank& ...

Running Selenium tests using a standalone or containerized server: A comprehensive guide

Regarding the initiation of a standalone Selenium server, I have observed that my junit test currently handles the startup of the Selenium server for me. However, I am interested in independently starting the server. // Example selenium test script using ...

Utilizing Ionic to seamlessly integrate Firebase into a factory, maintaining separation of controllers and services within distinct files

I'm struggling with setting up a firebase factory for use in my controllers. Currently, this is how my code appears: index.html ... <!-- integrating firebase --> <script src="lib/firebase/firebase.js"></script> <script src="lib/ ...