0

I have a React component, but the raw string:

<MyComponent id={123} value={345} name="Thomas" />

How can I regex through this string and extract all props & their value?

{
  id: 123,
  value: 345,
  name: "Thomas"
}

I am struggling to understand how to go about something like this.

I've tried things like this, but they aren't really getting me anywhere... :

let res = myComp.match(/.*<MyComponent id={.*/g)
let value = res[0].split('{')[1].split('}')[0]
antonwilhelm
  • 5,768
  • 4
  • 19
  • 45
  • If you are receiving that object as a string, you can use JSON.parse() to convert it into an object. Link: https://stackoverflow.com/questions/11171746/reverse-of-json-stringify – man517 Dec 18 '22 at 20:54
  • If the component is all there is to the string, you could just match the content of what looks like properties by using lookarounds to make sure what you match is framed by `={...}` or `="..."`. Something like `(?<=={)[^}]*(?=})|(?<==")[^"]*(?=")` used like `let results = 'component-markup'.match(/expression/g)`. – oriberu Dec 18 '22 at 21:33

3 Answers3

1

One option might be using a pattern with an infinite lookbehind assertion if supported and 3 capture groups with an alternation.

Assuming there are no other occurrences of < and > in the string:

(?<=<MyComponent\s[^<>]*)([^\s=]+)=(?:{([^{}]*)}|"([^"]*)")(?=[^<>]*\/>)

See a regex101 demo;

const regex = /(?<=<MyComponent\s[^<>]*)([^\s=]+)=(?:{([^{}]*)}|"([^"]*)")(?=[^<>]*\/>)/g;
const s = `<MyComponent id={123} value={345} name="Thomas" />`;
const result = {};
Array.from(s.matchAll(regex), m => {
  result[m[1]] = m[2] ? parseInt(m[2]) : m[3]
});
console.log(result);
The fourth bird
  • 154,723
  • 16
  • 55
  • 70
0

The following regexp should scan all of the name/value pairs. You can use this in a matchAll() to return an iterable object with all the matches. The name is in capture group 1 and the value can be gotten by concatenating groups 3, 4, and 5. You can add javascript code to iterate this structure and build your result string.

/([\w.:-]+)(\s*=\s*)(?:\{(.+?)\}|(".*?")(?<!\\")|(\w+))/gs

enter image description here

I added a little defensive check to handle escaped double-quotes inside double-quoted strings.

Chris Maurer
  • 2,339
  • 1
  • 9
  • 8
0

Given your string, another regex that would retrieve your values is the following:

(\b\S+\b)=[{"](\b\S+\b)["}]

Regex Explanation:

  • (\b\S+\b): Group 1, non-space characters sequence
  • =: =
  • [{"]: either open brace or double quotes
  • (\b\S+\b): Group 2, , non-space characters sequence
  • [}"]: either closed brace or double quotes

Check the demo here.

let text = "<MyComponent id={123} value={345} name=\"Thomas\" />";

let regex = /(\b\S+\b)=[{"](\b\S+\b)["}]/g;

let results = text.matchAll(regex);

for (result of results) {
  console.log("Key:", result[1], ' Value:', result[2])
}
lemon
  • 14,875
  • 6
  • 18
  • 38