marcint339
marcint339

Reputation: 358

Capitalize the beginning of each sentence

I would like to capitalize the beginning of each sentence. I have the following code from other question:

function applySentenceCase(str) {
    return str.replace(/.+?[\.\?\!](\s|$)/g, function (txt) {
        return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
    });
}

But if i don't put a dot for a last sentence, it doesn't work properly. For example: for string "THIS IS THE FIRST QUESTION. SECOND QUESTION" it returns "This is the first question. SECOND QUESTION"

Upvotes: 2

Views: 188

Answers (3)

nu11p01n73R
nu11p01n73R

Reputation: 26667

The issue with the regex is the grouping (...)

str.replace(/.+?(?:[.?!]\s|$)/g, function (txt) {
        return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
    });
// Outputs
//"This is the first question. Second question. Third question

Or in es6:

str.replace(/.+?(?:[.?!]\s|$)/g, txt => `${txt.charAt(0).toUpperCase()}${txt.substring(1).toLowerCase()}`);

Changes

  • [.?!] This is a character class. There is no need to escape characters in a class.

  • (?:[.?!]\s|$) This matches . or ? or ! followed by a space(\s) OR an end of string $


What is wrong with .+?[\.\?\!](\s|$)

  • [\.\?\!](\s|$) This one tries to match a . or ? or ! always which is followed by a space or end of sentence. But clearly the last part didn't have one

Upvotes: 4

Emil S. Jørgensen
Emil S. Jørgensen

Reputation: 6366

Match against /^.|\.\s*\w/.

The first part says uppercase the first character on the line.

The second part says find a .(end of previous sentence), any amount of white space (\s) followed by 1 alphanumeric character.

Then just replace all of it with an uppercase version.

var str = "this is the first question. second question.";

console.log(str.toLowerCase().replace(/^.|\.\s*\w/ig, function(txt) {
  return txt.toUpperCase()
}));

EDIT 1

If you get it in all uppercase, simply call toLowerCase() on the string before replacing.

Upvotes: -1

Francesco
Francesco

Reputation: 1413

I don't actually see the need to use regex in this case:

var sentences = "THIS IS THE FIRST QUESTION. SECOND QUESTION";
sentences.split('.').map(function(item) {
    var sentence = item.trim();
    return sentence.charAt(0).toUpperCase() + sentence.substr(1).toLowerCase();
}).join('. ');

Upvotes: 2

Related Questions