0

Using RegEx, I want to replace construction in my example into a div.

So, before:

::: foo
some text
:::

After:

<div class="foo">
some text
</div>

I found how it may be done (test), but my solution works for only one class. In other words, class is hard-coded into script:

<script>
document.body.innerHTML = document.body.innerHTML.replace(new RegExp(/(:::\s?[a-z])\w+/, 'g'), '<div class="foo">');
document.body.innerHTML = document.body.innerHTML.replace(new RegExp(/:::/, 'g'), '</div>');
</script>

How it may be changed, so it will work for any class name? For example, these constructions should be also converted into divs:

::: foobarfoo
some text
:::

and

::: foo-bar-foo_bar_foo123-foo
some text
:::
john c. j.
  • 725
  • 5
  • 28
  • 81
  • You need to [use captured groups](http://stackoverflow.com/questions/3954927/js-regex-how-to-replace-the-captured-groups-only) – yeputons Feb 17 '17 at 02:25

1 Answers1

1

You can use capturing groups, that is, put part of your regex in parentheses and then that part of the match will be captured for use in the replacement, where you can reference it with $1:

var text = document.body.innerHTML;
text = text.replace(/:::\s?([^\s:]+)/g, '<div class="$1">')
text = text.replace(/:::/g, '</div>');
document.body.innerHTML = text;

If you had more than one capturing group in the same regex the second and subsequent ones would be referenced by $2, $3, etc.

Note that you should avoid repeatedly updating document.body.innerHTML - better to put the original text into a variable, then do your replacements with that variable, then finally write the end result back to document.body.innerHTML. You can also chain the .replace() calls:

document.body.innerHTML = document.body.innerHTML
                           .replace(/:::\s?([^\s:]+)/g, '<div class="$1">')
                           .replace(/:::/g, '</div>');

Note also that you don't need to call new RegExp(), because the / at the beginning and end of the regex is the regex literal syntax that creates a regular expression object on its own.

nnnnnn
  • 147,572
  • 30
  • 200
  • 241
  • It works, and also, compared with some another answers, it really clean and easy to understand. – john c. j. Feb 17 '17 at 02:54
  • 1
    I forgot to explain in my answer, but (aside from the parentheses) where you had `[a-z]\w+` I changed it to `[^\s:]+`, that is, to match any characters other than spaces and colons. That made more sense to *me*, but obviously you can use `[a-z]\w+` or whatever else meets your needs. The parentheses/capturing groups is the main point of the question and answer. – nnnnnn Feb 17 '17 at 03:04