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

  • Try `text.replace(RegExp("{{.*?}}|(" + aTags[index].textContent + ")\\w*", "i"), function($0, $1) { return $1 ? "{{" + index + ":" + $1 + "}}" : $0;} )`, see http://jsfiddle.net/4bpkzhtd/1/. – Wiktor Stribiżew Jul 01 '18 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` –  Jul 02 '18 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. – Wiktor Stribiżew Jul 02 '18 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. – Wiktor Stribiżew Jul 02 '18 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 –  Jul 02 '18 at 12:17
  • Very frustrating to see it requires two people to explain things in every detail up to a point of providing a copy&pasteable solution. That essentially is a free coding service. – wp78de Jul 02 '18 at 17:46
  • @wp78de Sorry, I did not even notice your answer (I think it is due to the one deleted that appeared on top). – Wiktor Stribiżew Jul 03 '18 at 07:26
  • It happens, thanks @WiktorStribiżew – wp78de Jul 03 '18 at 07:40

2 Answers2

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.

wp78de
  • 18,207
  • 7
  • 43
  • 71
  • 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; }); –  Jul 02 '18 at 12:05
  • @j.sell sorry, you totally misinterpreted the pseudo-code. Fortunately, you are already covered. – wp78de Jul 02 '18 at 17:12
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.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • 1
    thank you for your answer, it worked finally, i need to read more on regex to understand them better –  Jul 02 '18 at 12:37