1

I have an array in string-format. With Javascript, how to replace [, ], <Tag: , and > in the least amount of code possible:

let s = "[<Tag: cats>, <Tag: dogs>, <Tag: parakeets>]"

End result should look like:

"cats, dogs, parakeets"

This seems to work, but it's pretty... not great.

s.replace(/^\[/, '').replace(/\]$/, '').replaceAll('<Tag: ', '').replaceAll('>', '')

Is there a clever way to do this with RegEx?

0

5 Answers 5

2

Matching <Tag: and then capturing non-> characters looks like it'd do what you want:

const s = "[<Tag: cats>, <Tag: dogs>, <Tag: parakeets>]";
const result = s.replace(/<Tag: ([^>]+)>/g, '$1').replace(/[[\]]/g, '');
console.log(result);

Another approach, matching instead of replacing:

const s = "[<Tag: cats>, <Tag: dogs>, <Tag: parakeets>]";
const result = [...s.matchAll(/<Tag: ([^>]+)>/g)]
  .map(match => match[1])
  .join(', ');
console.log(result);

Sign up to request clarification or add additional context in comments.

3 Comments

How about using (.+?) instead of ([^>]+)?
Lazy repetition, while it looks nicer, is less efficient than a negative character set
I just ran a benchmark: html.matchAll(/<[^>]+>/g) vs. html.matchAll(/<.+?>/g) on this page's HTML source code and the latter one was faster by 6.5%.
2

I would suggest matching all substrings and joining them:

const result = [...s.matchAll(/<Tag:\s*(\w+)>/g)]
    .map(
        ([, m]) => m
    )
    .join(', ');


// result: "cats, dogs, parakeets"

2 Comments

Slight issue. If tag is multi-word (ex: <Tag: something with spaces>) the regex needs to allow for spaces. I failed to provide an example in my initial question. I think ([\w\s]+) will work.
@Jarad yes, if you need spaces then what you suggested will work :)
1

When an infinite quantifier in a lookbehind is supported, you can match all the values between <Tag: and the > and make sure all the matches are between square brackets.

See the regex matches in this regex demo.

let s = "[<Tag: cats>, <Tag: dogs>, <Tag: parakeets>]"
const regex = /(?<=\[[^\][]*<Tag: )\w+(?=>[^\][]*\])/g;
console.log(s.match(regex).join(", "));

Comments

0

What about this? Remove the delimiters [, ], > and <Tag: parts:

let s = "[<Tag: cats>, <Tag: dogs>, <Tag: parakeets>]";
s = s.replace(/[[\]>]|<.*? /g, "");
console.log(s);

6 Comments

FYI: I didn't downvote. Your answer seems to work on my simple string. I too would like to know what might be wrong with your answer. It is probably the shortest.
I didn't downvote neither, but even though your answer will work in this case, when designing a pattern for regex, you should avoid false positives. It's just not the greatest pattern, may lead to unstable results.
Not my downvote, but there is imho no reason to use "<.*? " instead of "<Tag: ". This disallows spaces and brackets in the text, uses a ".*?" (which should be considerably more work than necessary, albeit this difference usually being irrelevant), and is harder to read and grasp the intention from, at least imho.
Some other answers create intermediate arrays... or perform two replace calls, and they get upvoted. I'm lost.
@trincot but they are more readable than yours.
|
0

Not using a regex but it does return the same result that need.

let res = ""
let s = "[<Tag: cats>, <Tag: dogs>, <Tag: parakeets>]"

for ( let i = 0; i < s.length; i++){
  let c = s[i]
  if ( c == '[' || c == ']' || c == '>')
    continue
  else if ( s.substr(i,5) == '<Tag:')
    i += 5
  else
    res += c
}
return res

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.