Ryan Davidson
Ryan Davidson

Reputation: 31

Checking if first character of each word is Uppercase

I would like to check if the first character of each word of a string is uppercase. Other characters should be lowercase.

For Example:

My Lady D'Arbanville => True
My Lady d'arbanville => False
My LADY D'Arbanville => False

I tried : ^[A-Z][a-z ']*$ but not working

Upvotes: 3

Views: 2114

Answers (4)

The fourth bird
The fourth bird

Reputation: 163217

If there can be a single quote between 2 uppercase chars, you can optionally repeat that.

^[A-Z](?:'[A-Z])*[a-z]+(?: [A-Z](?:'[A-Z])*[a-z]+)*$

The pattern matches:

  • ^ Start of string
  • [A-Z] Match a char in the range A-Z
  • (?:'[A-Z])* Optionally repeat ' and a char A-Z
  • [a-z]+ Match 1+ lowercase chars in range a-z
  • (?: Non capture group to repeat as a whole
    • [A-Z] Match an uppercase char
    • (?:'[A-Z])* Optionally repeat ' and an uppercase char
    • [a-z]+ Match 1+ chars in range a-z
  • )* Optonally repeat the non capture group preceded by a space
  • $ End of string

Regex demo

To also match a single uppercase char:

^[A-Z](?:'[A-Z])*[a-z]*(?: [A-Z](?:'[A-Z])*[a-z]*)*$

Regex demo

Upvotes: 5

RavinderSingh13
RavinderSingh13

Reputation: 133458

With your shown samples, please try following regex.

^[A-Z][a-z]+\s+[A-Z][a-z]+\s+[A-Z](?:'[A-Z])?[a-z]+$

Online demo for above regex

Explanation: Adding detailed explanation for above.

^[A-Z][a-z]+      ##Checking from starting of value if it starts from capital letter followed by 1 or more small letters here.
\s+               ##Matching 1 or more space occurrences here.
[A-Z][a-z]+       ##Matching 1 occurrence of capital letter followed by 1 or more small letters here.
\s+               ##Matching 1 or more space occurrences here.
[A-Z](?:'[A-Z])?  ##Matching single capital letter followed by optional ' capital letter here.
[a-z]+$           ##Matching 1 or more occurrences of small letters till end of value here.

Upvotes: 4

Casimir et Hippolyte
Casimir et Hippolyte

Reputation: 89547

Checking the negative condition is from far more simple:

\b[a-z]|\B[A-Z]

if this pattern succeeds, the condition is false.

Upvotes: 0

zer00ne
zer00ne

Reputation: 43870

I hate relying entirely on regex, it's hard to isolate edge cases or narrow down generalities. Although OP's question asks for a regex to an objective, there's simpler ways to meet this objective and leave room to adapt.

The function below will pass a string (ex. "My Lady D'Arbanville") then:

  1. .split() the string into an array of strings by removing a whitespace (\s) OR (|) a single quote (').

     `My Lady D'Arbanville`.split(/\s|'/);
    

    returns: ["My", "Lady", "D", "Arbanville"]

  2. .every() word in the array of strings will be tested by a function(). Each tested word must be true in order to report the given string as true.

     ["My", "Lady", "D", "Arbanville"].every(function(word) {})
    
  3. The function() will .test() each word to see if the following are true:

    • the first character is an upper case letter [A-Z]
    • all characters following the first character are lower case [a-z]+

    OR |

    • the \bword\b is a single character that is a letter in upper case [A-Z]
    /[A-Z][a-z]+|\b[A-Z]\b/.test(word)
    

const titleCheck = (text) => {
  const wordArray = text.split(/\s|'/);
  console.log(wordArray);
  return wordArray.every(word => {
    const rgx = new RegExp(/[A-Z][a-z]+|\b[A-Z]\b/);
    return rgx.test(word);
  });
};

/* true
Control 
*/
console.log(titleCheck(`My Lady D'Arbanville`));

/* false
A word starting with a lower case letter
*/
console.log(titleCheck(`My Lady D'arbanville`));

/* false
A word with any upper case letter that is
NOT the first letter
*/
console.log(titleCheck(`My LADY D'Arbanville`));

/* false
A single letter word that is lower case
*/
console.log(titleCheck(`My Lady d'Arbanville`));

Upvotes: 1

Related Questions