0

I would like to return all elements in array that appear after a certain word

For example given the string

let testPattern = '<name>ladder</name><prx>112</prx><qty>12</qty><name>ladder</name><prx>200</prx>'

I would get the output

['ladder', 'prx: 112', 'qty: 12', 'ladder', 'prx: 200']

This is the code I have

const result = testPattern
    .match(/<[a-z]+>(.*?)<\/[a-z]+>/g)
    .map(val => val.replace(/<(\w+)\>(.*)\<\/\1\>/g, '$1: $2')
    .substring(testPattern.indexOf('ladder'),testPattern.length)
    )

This is what I get

[ 'ladder', '12', '2', 'ladder' ,'00']

Where am I going wrong

Emm
  • 2,367
  • 3
  • 24
  • 50
  • 1
    Is the desired output an object or an array? You seem to be mixing the syntax of both. – Wais Kamal Jan 17 '22 at 16:20
  • 1
    It is also a very bad idea to parse XML using regex. Consider using an XML parser instead. – Wais Kamal Jan 17 '22 at 16:21
  • Why not simply parse this string as XML? ``new DOMParser().parseFromString(`${testPattern}`, "text/xml")``; you need the `` to make it parse as valid XML. The next steps depend on your desired result. What you’ve shown isn’t anything valid in JS. – Sebastian Simon Jan 17 '22 at 16:22
  • @WaisKamal desired out is an array. What do you mean mixing the syntax of both? – Emm Jan 17 '22 at 16:23
  • @Emm Then [edit] your post and correct it. Familiarize yourself with [how to access and process nested objects, arrays or JSON](/q/11922383/4642212) and how to [create objects](//developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Object_initializer) and use the available static and instance methods of [`Object`](//developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object#Static_methods) and [`Array`](//developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array#Static_methods). `[ ladder, prx: 112,`…`]` means nothing in JS. – Sebastian Simon Jan 17 '22 at 16:24
  • Looks like you’re looking for ``Array.from(new DOMParser().parseFromString(`${testPattern}`, "text/xml").documentElement.children, ({ nodeName, textContent }) => `${nodeName.toLowerCase() === "name" ? "" : nodeName.toLowerCase() + ": "}${textContent}`)``. – Sebastian Simon Jan 17 '22 at 16:28

1 Answers1

1

While you could do this with a regular expression, parsing the XML would make more sense.

let testPattern = '<name>ladder</name><prx>112</prx><qty>12</qty><name>ladder</name><prx>200</prx>';
const doc = new DOMParser().parseFromString(testPattern, 'text/html');
const arr = [...doc.body.children].map(
  child => child.nodeName === 'NAME' ? child.textContent : `${child.nodeName.toLowerCase()}: ${child.textContent}`
);
console.log(arr);

It's not actually HTML, but it still works.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • Getting the error: `TypeError: Cannot read properties of undefined (reading 'children')` – Emm Jan 17 '22 at 17:27
  • The code in the answer does not produce such an error - press "Run code snippet" to see it working for yourself. If you use the same code as the code in the answer, it'll work. – CertainPerformance Jan 17 '22 at 17:28