2

Say I have strings like this:

' <xxx > '
' < xxx >'
' < xxx>'
' < xxx'
' xxx<'
' xxx'

what's the easiest way to parse what's inside the brackets? If there is only one bracket but not the matching bracket, I can throw an error.

I figure a regex might be the easiest way?

Emma
  • 27,428
  • 11
  • 44
  • 69
  • You very likely do not need a regex for this. However, all your data examples show one pair of brackets at the start and end of the string. Will there ever be more than one pair of brackets? Is text allowed outside the brackets? You should really describe the rules for what to allow and exclude. – ziggy wiggy May 20 '19 at 10:12
  • you're right, the first 3 should succeed in parsing, the last 3 should fail, since they are missing a balanced pair of brackets, if you can think of a good to do this without regex lmk thx –  May 20 '19 at 17:21
  • Again, do you need to find multiple pairs in a string? Can they be nested? Is text allowed before and after the pairs? I can't give a solution without knowing the full requirements. – ziggy wiggy May 20 '19 at 23:47
  • Basically if there is a balanced pair of `<>` just want to get the literal text inside, I can trim() for whitespace afterwards....if there are multiple balanced pairs you can return all of them, but for my case there is only one pair expected, of course one of the < or > could be missing so have to account for that. –  May 21 '19 at 00:21
  • So these are valid? `< foo > bar >` ... `foo baz` – ziggy wiggy May 21 '19 at 03:58

3 Answers3

2

You can use string.match(). This will check if the string is valid.

const reg = /\<(.*?)\>/;

// Returns the inner value of the string, or FALSE
const getValue = v => {
  v = v.match(reg);
  return v ? v[1].trim() : false;
}

// Check single value 
let v1 = getValue(' < xxx>');
if (v1 !== false) {
  console.log(v1);
}

// Check multiple values 
const values = [' <xxx > ', ' < xxx >', ' < xxx>', ' < xxx', ' xxx<', ' xxx'];
let v2 = values.map(v => getValue(v));
console.log(v2);
Miroslav Glamuzina
  • 4,472
  • 2
  • 19
  • 33
  • You should use the `?` character to make the `.*` non-greedy for cases like `< xxx> yyy>`: `/\<(.*?)\>/`. I would also move the regex out of the function so it's not recompiled every time you call `getValue`. Finally, if you want to handle arbitrarily nested angle brackets e.g. `<, >` then you can't accomplish this simply with a regex – jakedipity May 20 '19 at 03:57
  • @JacobHull Thanks for the input :). I've updated my answer to use `?` to make the `.*` non-greedy, as well as pulling out the regex. – Miroslav Glamuzina May 20 '19 at 04:23
0

This could be achieved with the regex \<\s*([^>]+)\s*\>. This would capture xxx (no spaces on either side).

"<xxx>".match(/\<\s*([^>]+)\s*\>/) // [2] = 'xxx'
"<xxx >".match(/\<\s*([^>]+)\s*\>/) // [2] = 'xxx'
"xxx<".match(/\<\s*([^>]+)\s*\>/) // null
ug_
  • 11,267
  • 2
  • 35
  • 52
-1

Here, we can swipe everything from the left in our first capturing group, then add a list of our desired chars, collect them in our second capturing group:

([\s\S]*?)([a-z]+)

const regex = /([\s\S]*?)([a-z]+)/gm;
const str = ` <xxx >  
  < xxx > 
  < xxx> 
  < xxx 
  xxx< 
  xxx `;
const subst = `$2\n`;

// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);

console.log('Substitution result: ', result);

RegEx

If this expression wasn't desired, it can be modified or changed in regex101.com.

enter image description here

RegEx Circuit

jex.im also helps to visualize the expressions.

enter image description here

Emma
  • 27,428
  • 11
  • 44
  • 69