0

I have a string

text *inner text 1* text2 *inner text 2*

I have to replace the substrings with <span></span>

Output

text <span>inner text 1</span> text2 <span>inner text 2</span>

I tried this

replace(/[*]/g,"<span>")

I know using /g is going to replace all the occurrences with <span> also I cannot put two params in replace so the question is how to replace every even occurrences with </span>

Josiah
  • 207
  • 3
  • 13
Adarsh
  • 474
  • 1
  • 9
  • 17
  • Have you tried catching the "space*" and "*space" separately with their own regular expressions? – Josiah Mar 23 '20 at 14:17
  • The trick is to use backreferences in capturing groups of your regular expressions. https://javascript.info/regexp-backreferences has an example using quotation marks. Let me try to come up with an answer matching your use case. – Ryuno-Ki Mar 23 '20 at 14:18
  • @Ryuno-Ki - A regular expression could be a good answer here, but I don't think you need backreferences for this...? – T.J. Crowder Mar 23 '20 at 14:19

4 Answers4

2

Regex

\*([^\*]+)\*

let str = 'text *inner text 1* text2 *inner text 2*'

console.log(str.replace(/\*([^\*]+)\*/g, '<span>$1</span>'))

Demo

https://regex101.com/r/wj9WkA/1/

User863
  • 19,346
  • 2
  • 17
  • 41
1

You can use a counter and the remainder operator, giving a callback to replace:

let counter = 0;
result = original.replace(/[*]/g, () => ++counter % 2 ? "<span>" : "</span>");

Live Example:

const original = "text *inner text 1* text2 *inner text 2*";
let counter = 0;
const result = original.replace(/[*]/g, () => ++counter % 2 ? "<span>" : "</span>");
console.log(result);

That works because 1 % 2 is 1 which is truthy, but 2 % 2 is 0 which is falsy, and 3 % 2 is 1 which is truthy...

Another approach would be to use a regular expression to search for matches between two *, using a capture group to capture the matches:

result = original.replace(/\*(.*?)\*/g, "<span>$1</span>");

Live Example:

const original = "text *inner text 1* text2 *inner text 2*";
let counter = 0;
const result = original.replace(/\*(.*?)\*/g, "<span>$1</span>");
console.log(result);

That's assuming it's really okay to work purely on the basis of alternating * characters.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
0

You may use:

str.replace(/([*])([\w ]+)\1/g, '<span>$2</span>');

RegEx Details:

  • ([*]) Match * and capture in group #1
  • ([\w ]+) Match 1+ word or space character and capture in group #2
  • \1 is used to make string ends with same * as in group #1
  • Replacement is <span>$2</span> to wrap string in group #2 in <span> and </span>

Demo:

const str = 'text *inner text 1* text2 *inner text 2*';

const res = str.replace(/([*])([\w ]+)\1/g, '<span>$2</span>');

console.log(res);
palaѕн
  • 72,112
  • 17
  • 116
  • 136
0

Short answer based on https://stackoverflow.com/a/1234725/5189920:

var string = 'text *inner text 1* text1 *inner text 2* text2';
var newString = string.replace(/\*([\w\s]+[^*])\*/g, '<span>$1</span>');
console.log(newString);

Explanation: The regular expression is searching for a literal asterisk (\*), followed by a capturing group ((...)). This group can be referenced back by $1 in the second argument. In it, we are capturing all word (\w) and whitespace (\s) up until the next asterisk ([^*]). The search applies globally (/g).

The second argument is referenced the captured group and replaced the parts around it (\*).

Ryuno-Ki
  • 692
  • 1
  • 6
  • 8