0

Hoping someone might help. I have a string formatted like the example below:

Lipsum text as part of a paragraph here, yada. |EMBED|{"content":"foo"}|/EMBED|. Yada and the text continues...

What I am looking for is a Javascript RegEx to capture the content between the |EMBED||/EMBED| 'tags', run a function on that content, and then to replace the entire |EMBED|...|/EMBED| string with the return of that function.

The catch is that I may have multiple |EMBED| blocks within a larger string. For example:

Yabba...|EMBED|{"content":"foo"}|/EMBED|. Dabba-do...|EMBED|{"content":"yo"}|/EMBED|.

I need the RegEx to capture and process each |EMBED| block separately, since the content contained within will be similar, but unique.

My initial thought is that I could just have a RegEx that captures the first iteration of the |EMBED| block, and the function which replaces this |EMBED| block is either part of a loop or recursion to continuously find the next block and replace it, until no more blocks are found in the string.

...but this seems expensive. Is there a more eloquent way?

4
  • 2
    So where are you stuck? Please post the regex you used and explain what the problem is. Commented Mar 24, 2017 at 19:43
  • Use a non-greedy quantifier, or use a negative lookahead. Commented Mar 24, 2017 at 19:44
  • Why does it have to be an iteration and not a single function call? Commented Mar 24, 2017 at 19:46
  • @WiktorStribiżew, I was stuck finding a better solution than the one I proposed. But it seems that a few authors below have given me a really good and potentially less expensive solution than the one I had in mind. Commented Mar 24, 2017 at 21:47

2 Answers 2

2

You can use String.prototype.replace to replace a substring found via a regular expression with a modified version of the match using a mapping function, e.g.:

var input = 'Yabba...|EMBED|{"content":"foo"}|/EMBED|. Dabba-do...|EMBED|{"content":"yo"}|/EMBED|.'

var output = input.replace(/\|EMBED\|(.*?)\|\/EMBED\|/g, function(match, p1) {
  return p1.toUpperCase()
})

console.log(output) // "Yabba...{"CONTENT":"FOO"}. Dabba-do...{"CONTENT":"YO"}."


Make sure that you use a non-greedy selector .*? to select the content between the delimiters to allow multiple replacements per string.

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

2 Comments

This looks the most eloquent. Will test later today or tomorrow (when I can jump back into the project that needs this) and will mark my question resolved if everything works as expected!
For some reason I needed to use function(match, p0, p1) instead of function(match, p1) for p1 to match the content inside my tag, but it worked. Very elegant. Thank you!
1

This is the cod which iterate through the matches of the regex:

var str = 'Lipsum text as part of a paragraph here, yada. |EMBED|{"content":"foo"}|/EMBED|. Yada and the text continues...';
var rx = /\|EMBED\|(.*)\|\/EMBED\|/gi;
var match;
while (true)
{
    match = rx.exec(str);
    if (!match)
        break;
    console.log(match[1]); //match[1] is the content between "the tags"
}

1 Comment

Thank you, though I think @Timo's solution below might be an even shorter way to achieve my goal. Appreciate the time you took to write out my looping idea into code!

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.