62

Is it possible in JavaScript to find out if the first letter of a word is a capital letter?

Penny Liu
  • 15,447
  • 5
  • 79
  • 98
James J
  • 793
  • 1
  • 6
  • 9

8 Answers8

115

update

Updating with what i think is the most valid approach nowadays.

You can use a Unicode property escapes Regular expression if the support suits you. In this case you can use the General category property for Uppercase Letter Lu.

function isUppercase(word){
  return /^\p{Lu}/u.test( word );
}

older answers

var word = "Someword";
console.log( word[0] === word[0].toUpperCase() );

or

var word = "Someword";
console.log( /[A-Z]/.test( word[0]) );

or

var word = "Someword";
console.log( /^[A-Z]/.test( word) );

See toUpperCase() and test()

Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317
  • @Johnston : Look like you are misinterpreting the results from jsperf. The last option (/^[A-Z]/.test( word) ) seems to be the fastest. Check the test. The higher the value the better. – Pratham Mar 16 '15 at 10:53
  • 1
    @Pratham It depends on the computer that is running it. But here is a screenshot of what my results look like. http://imgur.com/nv4nBE7. It says that the uppercase version does 13m ops/sec while the other does 5m ops/sec. It also says on mine that the regex is 60% slower. Am I reading it wrong? – Johnston Mar 16 '15 at 10:59
  • 1
    @Johnston : Result from Firefox browser : http://imgur.com/1quk2fe . Looks like browser affects the performance – Pratham Mar 16 '15 at 11:05
  • These are fine if you know you're only getting a string containing A-Z English characters, but the regex will misidentify accented / on-ASCII capital letters (e.g. it'll return false for the names 'Łukasz' and Åland) and the `toUpperCase()` will treat non-letters like capital letters (e.g. it'll return true for '1940s' or '17th'). I've [added a (just as simple) alternative that meets these cases too](http://stackoverflow.com/a/39292247/568458). – user56reinstatemonica8 Sep 02 '16 at 12:27
35

The other answers on this page are fine for strings that are known to only contain non-accented A-Z letters. If you can't guarantee this (e.g. user input), they may give unexpected results: false positives for uncapitalisable initials like "1940s" or "中文", or false negatives for accented or non-Roman capital initials like "Łukasz" or "Александра".

This variant returns true if the initial is any capital letter, and only if it's a capital letter:

function initialIsCapital( word ){
  return word[0] !== word[0].toLowerCase();
}

Use .charAt(0) instead of [0] if you need IE8 support. Which is faster varies between browsers.

This avoids two potential pitfalls with the other answers:

  • Regexes using [A-Z] will fail to match accented and other similar non-A-Z capitalised letters such as in Åland (Scandinavian islands) and Łukasz (common Polish name), including capital letters in non-latin scripts such as Cyrillic or Greek (e.g. Александра).

  • The approach using word[0] === word[0].toUpperCase(), will return true on words that start with non-letters, such as 1940s, 17th, 123reg (company name), abbreviations like 2mrw, or some words in some African languages, such as !xūún or ǂǐ-sì. It'll also treat any input from an alphabet that doesn't have capital letters as being capital letters (e.g. 中文).

Since this arbitrary-input-safe approach is just as simple and no less readable than the alternatives, it's probably better to use this even if you don't anticipate such exceptions.

Here's a quick test:

function a(word){
  return word[0] !== word[0].toLowerCase();
}
function b(word){
  return word[0] === word[0].toUpperCase();
}
function c(word){
  return /^[A-Z]/.test( word );
}
function test(word, answer){
  console.log( 'Should be '+answer+':',  a(word), b(word), c(word), '-------', word );
}

test( 'Łukasz', true ); // regex test fails, returns false
test( 'Александра', true ); // regex test fails, returns false
test( '1940s', false ); // .toUpperCase() test fails, returns true
test( '中文', false ); // .toUpperCase() test fails, returns true

test( 'ß', false ); // All pass on German "sharp S" that has no uppercase
test( 'Z̢̜̘͇̹̭a͎͚͔͕̩̬̭͈͞l̩̱̼̤̣g̲̪̱̼̘̜͟ợ̮̱͎̗̕ͅͅ', true ); // All pass. Phew, Zalgo not awakened 
user56reinstatemonica8
  • 32,576
  • 21
  • 101
  • 125
12

For English letters only:

'A' => 65
'Z' => 90

Meaning, every number between [65, 90] is a capital letter:

function startsWithCapitalLetter(word) {
  return word.charCodeAt(0) >= 65 && word.charCodeAt(0) <= 90;
}
zurfyx
  • 31,043
  • 20
  • 111
  • 145
8

Yes.

var str = "Hello";
if(str[0].toUpperCase() == str[0])
{
   window.alert('First character is upper case.');  
}
Mike Christensen
  • 88,082
  • 50
  • 208
  • 326
  • 1
    Recommended since this seems to work, with a small amount of testing in Chrome, for Unicode characters like "È" (E with a grave) and "ζ" (non-capital zeta). – Lachlan McDonald Dec 01 '11 at 00:11
5

You can do it in several ways:

var myWord = "Hello";

// with string functions
if (myWord.charAt(0) === myWord.charAt(0).toUpperCase()) { /* is upper */ }

// or for newer browsers that support array-style access to string characters
if (myWord[0] === myWord[0].toUpperCase()) { /* is upper */ }

// with regex - may not be appropriate for non-English uppercase
if (/^[A-Z]/.test(myWord) { /* is upper */ }

Note that the array-style access to characters like myWord[0] is an ECMAScript 5 feature and not supported in older browsers, so (for now) I'd probably recommend the .charAt() method.

If you need to do this test a lot you could make a little function:

function firstLetterIsUpper(str) {
   var f = str.charAt(0);   // or str[0] if not supporting older browsers
   return f.toUpperCase() === f;
}

if (firstLetterIsUpper(myWord)) { /* do something */ }
nnnnnn
  • 147,572
  • 30
  • 200
  • 241
2

Using the match method of the string object prototype:

const word = 'Someword';
console.log(word.match(new RegExp(/^[A-Z]/)) !== null);
Penny Liu
  • 15,447
  • 5
  • 79
  • 98
jcroll
  • 6,875
  • 9
  • 52
  • 66
  • This might answer the question, but please also provide a short explanation, what your code does and why it solves the initial problem. – user1438038 Jul 25 '17 at 16:24
  • this is a regular experession matcher. read up yourself on language docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match – Tchakabam Jun 07 '21 at 11:41
  • Regular-expressions ("RegEx") btw are not specific to JS, it is a topic of its own for which there are enough tutorials out there. – Tchakabam Jun 07 '21 at 11:42
0

Typescript

//userEntry input as string
//return boolean
oneUppercaseRequired(userEntry: string): boolean {
   const letters = /[A-Z]/;

   if (letters.test(userEntry[0]))
     return true;

   return false;
}

for-loop for other languages Change the syntax to your language!

//userEntry param as string
//return boolean
oneUppercaseRequired(userEntry: string): boolean {
   const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

   for (let i = 0; i < letters.length; i++) {
     if (userEntry[0] == letters[i])
       return true;
   }

   return false;
}
Reza Taba
  • 1,151
  • 11
  • 15
  • You shouldn't hard-code logic for specific languages; if language is relevant, it's likely a user setting with multiple possibilities, and `toLowerCase` etc already covers every unicode character that is uppercase. No need to re-invent the wheel, creating brittle logic that only works for one language. Also, style tip: you never need `if (condition) { return true } return false`, `test` and `===` return booleans already, you can simply do `return someRegex.test(someString)`; and if you needed to loop through a string, you could do `return someString.includes(subString)`. – user56reinstatemonica8 Mar 10 '21 at 15:51
  • Misleading answer: The TypeScript code also works same for JavaScript (just remove the type annotations and you re fine, it is the same built in String functions). The for-loop approach is viable, but ineffctive (not to be used when reg-ex matchers available). This answer doesn't add anything to this already given one here: https://stackoverflow.com/a/45307750/589493 – Tchakabam Jun 07 '21 at 11:44
0
var string1 = "this is a string";
var string2 = "This is a string";

if(string1[0] == string1[0].toUpperCase())
    alert('is upper case');
else
    alert('is not upper case');


if(string2[0] == string2[0].toUpperCase())
    alert('is upper case');
else
    alert('is not upper case');
smnbss
  • 1,031
  • 1
  • 10
  • 21