Adarsh
Adarsh

Reputation: 524

Replacing substring in a numeric pattern

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>

Upvotes: 0

Views: 49

Answers (4)

palaѕн
palaѕн

Reputation: 73906

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);

Upvotes: 0

Ryuno-Ki
Ryuno-Ki

Reputation: 800

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 (\*).

Upvotes: 0

T.J. Crowder
T.J. Crowder

Reputation: 1074385

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.

Upvotes: 1

User863
User863

Reputation: 20039

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/

Upvotes: 2

Related Questions