Make first character uppercase but not after specific word

I am writing JavaScript code. The aim is to make every first character of a word uppercase after full-stop character (Hello world. Hi) while typing in textarea.

For that I’m using following code …

$('#div2').on('input', function (evt) {
    var re = /(^|[.!?]\s+)([a-z])/g;
    var box = evt.target;
    var stringStart = box.selectionStart;
    var stringEnd = box.selectionEnd; 
    var val = $(evt.target).val().replace(re, function (m, $1, $2) {
        return $1 + $2.toUpperCase()
    });

    $(evt.target).val(val);
    box.setSelectionRange(stringStart, stringEnd); 
});

Which works as expected.
But now i want it should skip some word like (U.S.A.). if one typed the the word U.S.A. in textare the first character of next word should not be uppercase.

E.g. 

    U.S.A. is the //Expected  
    U.S.A. Is the //what i am getting (wrong) 

To achive this i wrote below code, which not working as expected.

var skipWordUpper = ['U.S.A.', 'Inc.'];
$('#div2').on('input', function (evt) {
    var re = /(^|[.!?]\s+)([a-z])/g;
    var box = evt.target;
    var stringStart = box.selectionStart;
    var stringEnd = box.selectionEnd;

    var str = $('#div2').val();
    var beforeSpace = str.split(" ").splice(-2) 
    var foundPresent = $.inArray(beforeSpace[0], skipWordUpper) > -1; 

    if (!foundPresent) {
        var val = $(evt.target).val().replace(re, function (m, $1, $2) {
            return $1 + $2.toUpperCase()
        });

        $(evt.target).val(val);
        box.setSelectionRange(stringStart, stringEnd);
    } 
});

Anybody will plz help to find out what mistake i am making and put me in proper way.
or any changes in regular exp. is required.
Apology for my hellybelly knowledge of JAVASCRIPT

29 thoughts on “Make first character uppercase but not after specific word”

  1. Try using a negative lookbehind to exclude those words in the regular expression:

    $('#div2').on('input', function(evt) {
      var re = /(?<![U.S.A|Inc])([.!?]\s+)([a-z])/g;
      var box = evt.target;
      var stringStart = box.selectionStart;
      var stringEnd = box.selectionEnd;
    
      var str = $('#div2').val();
    
      var val = $(evt.target).val().replace(re, function(m, $1, $2) {
        return $1 + $2.toUpperCase()
      });
    
      $(evt.target).val(val);
      box.setSelectionRange(stringStart, stringEnd);
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <textarea id="div2"></textarea>
    Reply
  2. An approach to play with, based on something similar to e.g. …

    /(?<!\b(?:inc|pease|nope|U\.S\.A|u\.s\.w))([.?!]\s+)(\w)/gi

    Please also note that lookbehind assertions according to MDN and to caniuse are not supported widely amongst commonly used JS-engines, especially not with applying the full grammar of an regex to a lookbehind, like demonstrated with the following test case …

    function toRegExpSearch(str) {
      return String(str)
        .replace((/[$^*+?!:=.|(){}[\]\\]/g), match => `\\${ match }`)
        .replace((/\s+/g), '\\s+');
    }
    
    const regXFirstWordCharAfterFullstop = (/([.?!]\s+)(\w)/g);
    let regXFirstWordCharAfterFullstopException;
    
    // please also have a look into ... [https://regex101.com/r/zQ1gzo/1/]
    
    function updateFullstopExceptionRegX(evt) {
      const exceptionPattern = evt.currentTarget.value
        .trim()
        .split(/\s*,\s*|\s+/)
        .map(str => toRegExpSearch(str.replace((/\.$/g), '')))
        .join('|');
    
      regXFirstWordCharAfterFullstopException = RegExp(
        `(?<!\\b(?:${ exceptionPattern }))([.?!]\\s+)(\\w)`,
        'gi'
      );
    
      document
        .querySelector('#regx')
        .textContent = regXFirstWordCharAfterFullstopException;
    
      sanitizeText({
        currentTarget: document.querySelector('#text')
      });
    }
    
    function sanitizeText(evt) {
      const textElm = evt.currentTarget;
      const { selectionStart, selectionEnd } = textElm;
    
      textElm.value = textElm.value
        .replace(
          regXFirstWordCharAfterFullstop,
          (_, $1, $2) => $1 + $2.toLowerCase()
        )
        .replace(
          regXFirstWordCharAfterFullstopException,
          (_, $1, $2) => $1 + $2.toUpperCase()
        );
      textElm.setSelectionRange(selectionStart, selectionEnd);
    }
    
    function init() {
      document
        .querySelector('#skiplist')
        .addEventListener('input', updateFullstopExceptionRegX);
      document
        .querySelector('#text')
        .addEventListener('input', sanitizeText);
    
      updateFullstopExceptionRegX({
        currentTarget: document.querySelector('#skiplist')
      });
      sanitizeText({
        currentTarget: document.querySelector('#text')
      });
    }
    init();
    input, textarea {
      display: block;
      width: 100%;
      margin: 0;
    }
    pre { margin: 3px 0; padding: 0; }
    <input id='skiplist' type="text" placeholder="... add word or abbreviation to skiplist ..." value="inc. pease, nope, U.S.A. u.s.w." />
    
    <pre><code id="regx">(/(?:)/)</code></pre>
    
    <textarea cols="40" rows="9" id="text" placeholder="...type or paste text freely...">
    U.S.A. Is the country? i want to live in. if you please. yes. nope.
    U.S.A. Is the country? i want to live inc. If you pease. Dope. yes.
    U.S.A. Is the country? i want to live Inc. If you pease. Dope. yes.
    
    u.s.w. And so on. a German abbreviation.
    u.s.w. And so on. a German abbreviation.
    </textarea>
    Reply

Leave a Comment