Cian W
Cian W

Reputation: 106

Regex Capture Groups to Upper Case

If I'm using this code to make words bold how do I go about also making them uppercase?

var vow = "Night gathers, and now my watch begins. It shall not end until my death. I shall take no wife, hold no lands, father no children. I shall wear no crowns and win no glory. I shall live and die at my post. I am the sword in the darkness. I am the watcher on the walls. I am the shield that guards the realms of men. I pledge my life and honor to the Night's Watch, for this night and all the nights to come.";

var wordsToBold=["night","watcher"];

function makeBold(input, wordsToBold) {
return input.replace(new RegExp('(\\b)(' + wordsToBold.join('|') + ')(\\b)','ig'), '$1<b>$2</b>$3');
}

document.getElementById("vow_p").innerHTML = makeBold(vow, wordsToBold);

Upvotes: 1

Views: 1020

Answers (3)

Mr. Polywhirl
Mr. Polywhirl

Reputation: 48693

You can essentially build a regular expression by joining all the words as such:

(\b)(night|watch)(\b)

This regular expression will find all bounded-words that match any of the words requested to be bolded.

I added a mapping function to transform each word expression to support plurals and possessive nouns.

var vow = "Night gathers, and now my watch begins. It shall not end until my death. I shall take no wife, hold no lands, father no children. I shall wear no crowns and win no glory. I shall live and die at my post. I am the sword in the darkness. I am the watcher on the walls. I am the shield that guards the realms of men. I pledge my life and honor to the Night's Watch, for this night and all the nights to come.";

document.body.innerHTML = makeBold(vow, ['night', 'watcher'], 'bold');

function makeBold(passage, words, className) {
  return passage.replace(
    new RegExp('(\\b)(' + words.map(function(word) {
      return word + '[\'s]*'; // Capture (most) plurals and possessive nouns.
    }).join('|') + ')(\\b)', 'ig'),
    '$1<span class="' + className + '">$2</span>$3');
}
.bold {
  font-weight: bold;
  text-transform: uppercase;
}

Upvotes: 0

David Thomas
David Thomas

Reputation: 253446

One approach is to use CSS to style the <b> elements within the #vow_p element:

var vow = "Night gathers, and now my watch begins. It shall not end until my death. I shall take no wife, hold no lands, father no children. I shall wear no crowns and win no glory. I shall live and die at my post. I am the sword in the darkness. I am the watcher on the walls. I am the shield that guards the realms of men. I pledge my life and honor to the Night's Watch, for this night and all the nights to come.";

var wordsToBold=["night","watcher"];

function makeBold(input, wordsToBold) {
return input.replace(new RegExp('(\\b)(' + wordsToBold.join('|') + ')(\\b)','ig'), '$1<b>$2</b>$3');
}

document.getElementById("vow_p").innerHTML = makeBold(vow, wordsToBold);
#vow_p b {
  font-weight: bold;
  text-transform: uppercase;
}
<p id="vow_p"></p>

Alternatively, you can use the replace() method's anonymous function to convert the matched-string to upper-case format:

var vow = "Night gathers, and now my watch begins. It shall not end until my death. I shall take no wife, hold no lands, father no children. I shall wear no crowns and win no glory. I shall live and die at my post. I am the sword in the darkness. I am the watcher on the walls. I am the shield that guards the realms of men. I pledge my life and honor to the Night's Watch, for this night and all the nights to come.";

var wordsToBold = ["night", "watcher"];

function makeBold(input, wordsToBold) {
  return input.replace(new RegExp('(\\b)(' + wordsToBold.join('|') + ')(\\b)', 'ig'), function(match) {

    // match, the first argument to the function, is the matched
    // string which we make uppercase, using
    // String.prototype.toUpperCase(), and return as the replacement
    // string concatenated with the html for wrapping that string
    // in a <b> element:
    return '<b>' + match.toUpperCase() + '</b>';

  });
}

document.getElementById("vow_p").innerHTML = makeBold(vow, wordsToBold);
<p id="vow_p"></p>

Further it's worth noting that what you're asking for is presentational, rather than semantic, change; in which case this should be the purview of CSS rather than JavaScript.

Because there's no specific semantic need for those particular words to be strong (<strong>, or <b>), they would be as easily and accurately represented by a non-semantic <span> element, with a class-name to apply the presentational requirements:

var vow = "Night gathers, and now my watch begins. It shall not end until my death. I shall take no wife, hold no lands, father no children. I shall wear no crowns and win no glory. I shall live and die at my post. I am the sword in the darkness. I am the watcher on the walls. I am the shield that guards the realms of men. I pledge my life and honor to the Night's Watch, for this night and all the nights to come.";

var wordsToBold = ["night", "watcher"];

function makeBold(input, wordsToBold) {
  return input.replace(new RegExp('(\\b)(' + wordsToBold.join('|') + ')(\\b)', 'ig'), '$1<span class="keyWords">$2</span>$3');
}

document.getElementById("vow_p").innerHTML = makeBold(vow, wordsToBold);
span.keyWords {
  font-weight: bold;
  text-transform: uppercase;
}
<p id="vow_p"></p>

Upvotes: 1

Zbynek Vyskovsky - kvr000
Zbynek Vyskovsky - kvr000

Reputation: 18855

You can simply provide a callback to do complex operations:

function makeBoldAndUpper(input, wordsToBold) {
    return input.replace(
        new RegExp('\\b(' + wordsToBold.join('|') + ')  \\b','ig'),
        function(match, capture) { return "<b>"+match.toUpperCase()+"</b>"; });
}

Upvotes: 1

Related Questions