0

Am trying to find a regex expression for this result:

string => should be matched (a single word or set of words at the beginning or the ending)
 string  => should be matched (a single word or set of words in the middle)
{{string}} -- should not be matched (a single word or set of words surrounded by two "{}" should not be matched)

am using this regex in this function :

text = text.replace(RegExp("([^{]{2})[^(\d:)]" + aTags[index].textContent + "\w* 
([^}]{2})", 'i'), "{{" + index + ":" + aTags[index].textContent + "}}");

the function should find the textContent of an 'a' tag in a 'text' string and replace it by adding a digit and ':' to the beginning of the textContent so that the result should be something like this :

some text => will became => {{1:some text}}

regex on regex101

8
  • Try text.replace(RegExp("{{.*?}}|(" + aTags[index].textContent + ")\\w*", "i"), function($0, $1) { return $1 ? "{{" + index + ":" + $1 + "}}" : $0;} ), see jsfiddle.net/4bpkzhtd/1. Commented Jul 1, 2018 at 19:57
  • hi, thank you for your comment , the problem with your answer is that it match {{string}} witch i don't want to match it i need to skip it, this one : text = text.replace(RegExp("{{[^}]+}}|(" + aTags[index].textContent + ")", 'gmi'), function (match, $1) { if($1) return $1 ? {{${index}:${$1}}} : match; }); worked on regex101 but in javascript i get this error Invalid regular expression: /{{[^}]+}}|(*SKIP what's to avoid approach)/: Nothing to repeat Commented Jul 2, 2018 at 12:11
  • You cannot "skip" anything in a JavaScript regex , it is not PCRE. You should match and capture it and then add some programming logic around it - see my snippet - doesn't it produce the results you need? In my snippet, I match {{...}}, but I do skip it in the code. Commented Jul 2, 2018 at 12:13
  • I strongly advise to first understand the basics of JS regex before trying to meddle with the regex testers, and be very careful with options you select there. Commented Jul 2, 2018 at 12:17
  • yes you right, i modified my code like this : text = text.replace(RegExp("{{[^}]+}}|(" + aTags[index].textContent + ")", 'gmi'), function (match, $1) { return $1 ? {{${index}:${$1}}}` : match; });` it worked now , thanks Commented Jul 2, 2018 at 12:17

2 Answers 2

2

We can apply the good old *SKIP what's to avoid approach and throw everything that does not need to be replaced in the full match and capture the desired output in group 1:

{{[^}]+}}|(string)

To make this work effectively in JavaScript we have to use a .replace callback function:

const regex = /{{[^}]+}}|(string)/gm;
const str = `string 
 string  
{{string}}`;

var index = 1; //this is your index var and is somehow set from outside
const result = str.replace(regex, function(m, group1) {
    if (group1) return `{{${index}:${group1}}}`;
    else return m;
});
console.log('Substitution result: ', result);

I had pseudo-coded this a bit since I cannot know where index and aTags[index].textContent is coming from. Adjust as needed.

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

2 Comments

hi , thank you for your answer, i modified my code to match you answer but i get this error : Invalid regular expression: /{{[^}]+}}|(*SKIP what's to avoid approach)/: Nothing to repea , here is the function : text = text.replace(RegExp("{{[^}]+}}|(" + aTags[index].textContent + ")", 'gmi'), function (match, $1) { if($1) return $1 ? {{${index}:${$1}}} : match; });
@j.sell sorry, you totally misinterpreted the pseudo-code. Fortunately, you are already covered.
0

You cannot use PCRE verbs like (*SKIP)(*F) in a JavaScript regex, i.e. you cannot skip a matched portion of text with the regex means only. In JavaScript, you may match and capture a part of the string you want to later analyze in the replacement callback method (JS String#replace accepts a callback as the replacement argument).

So, in your case the solution will look like

text = text.replace(RegExp("{{.*?}}|(" + aTags[index].textContent + ")", "gi"),
    function ($0, $1) { 
        return $1 ? "{{" + index + ":" + $1 + "}}" : $0; 
    }
);

I understand the aTags[index].textContent value is alphanumeric, else, consider escaping it for use in a regex pattern.

The pattern will match a {{...}} substring having no } inside (with {{.*?}}) or (|) it will match and capture the text content ((aTags[index].textContent)) into Group 1. When you get a match, you need to pass 2 arguments to the callback, the whole match and Group 1 value. If Group 1 is not empty, you perform string manipulations, else, just insert the match back.

1 Comment

thank you for your answer, it worked finally, i need to read more on regex to understand them better

Your Answer

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