• Jump To … +
    abbreviations.js adjectives.js convertables.js dates.js demonyms.js firstnames.js honourifics.js irregular_nouns.js irregular_verbs.js misc.js multiples.js numbers.js organisations.js phrasal_verbs.js places.js uncountables.js verbs.js fns.js index.js lexicon.js negate.js passive_voice.js contractions.js fancy_lumping.js grammar_rules.js parts_of_speech.js phrasal_verbs.js tagger.js word_rules.js question.js sentence.js statement.js tense.js adjective.js to_adverb.js to_comparative.js to_noun.js to_superlative.js adverb.js to_adjective.js is_acronym.js article.js date.js date_rules.js is_date.js parse_date.js is_plural.js is_uncountable.js noun.js is_organisation.js organisation.js gender.js is_person.js parse_name.js person.js is_place.js place.js pluralize.js pronoun.js singularize.js is_value.js numbers.js to_number.js units.js value.js term.js conjugate.js from_infinitive.js predict_form.js suffix_rules.js to_actor.js to_infinitive.js negate.js verb.js sentence_parser.js text.js
  • is_plural.js

  • ¶
    'use strict';
    const irregulars = require('../../data/irregular_nouns');
  • ¶

    similar to plural/singularize rules, but not the same

    const plural_indicators = [
      /(^v)ies$/i,
      /ises$/i,
      /ives$/i,
      /(antenn|formul|nebul|vertebr|vit)ae$/i,
      /(octop|vir|radi|nucle|fung|cact|stimul)i$/i,
      /(buffal|tomat|tornad)oes$/i,
      /(analy|ba|diagno|parenthe|progno|synop|the)ses$/i,
      /(vert|ind|cort)ices$/i,
      /(matr|append)ices$/i,
      /(x|ch|ss|sh|s|z|o)es$/i,
      /men$/i,
      /news$/i,
      /.tia$/i,
      /(^f)ves$/i,
      /(lr)ves$/i,
      /(^aeiouy|qu)ies$/i,
      /(m|l)ice$/i,
      /(cris|ax|test)es$/i,
      /(alias|status)es$/i,
      /ics$/i
    ];
  • ¶

    similar to plural/singularize rules, but not the same

    const singular_indicators = [
      /(ax|test)is$/i,
      /(octop|vir|radi|nucle|fung|cact|stimul)us$/i,
      /(octop|vir)i$/i,
      /(rl)f$/i,
      /(alias|status)$/i,
      /(bu)s$/i,
      /(al|ad|at|er|et|ed|ad)o$/i,
      /(ti)um$/i,
      /(ti)a$/i,
      /sis$/i,
      /(?:(^f)fe|(lr)f)$/i,
      /hive$/i,
      /(^aeiouy|qu)y$/i,
      /(x|ch|ss|sh|z)$/i,
      /(matr|vert|ind|cort)(ix|ex)$/i,
      /(m|l)ouse$/i,
      /(m|l)ice$/i,
      /(antenn|formul|nebul|vertebr|vit)a$/i,
      /.sis$/i,
      /^(?!talis|.*hu)(.*)man$/i
    ];
    
    const is_plural = function(str) {
      str = (str || '').toLowerCase();
  • ¶

    handle ‘mayors of chicago’

      const preposition = str.match(/([a-z]*) (of|in|by|for) [a-z]/);
      if (preposition && preposition[1]) {
        str = preposition[1];
      }
  • ¶

    if it’s a known irregular case

      for (let i = 0; i < irregulars.length; i++) {
        if (irregulars[i][1] === str) {
          return true;
        }
        if (irregulars[i][0] === str) {
          return false;
        }
      }
      for (let i = 0; i < plural_indicators.length; i++) {
        if (str.match(plural_indicators[i])) {
          return true;
        }
      }
      for (let i = 0; i < singular_indicators.length; i++) {
        if (str.match(singular_indicators[i])) {
          return false;
        }
      }
  • ¶

    some ‘looks pretty plural’ rules

      if (str.match(/s$/) && !str.match(/ss$/) && str.length > 3) { //needs some lovin'
        return true;
      }
      return false;
    };
  • ¶

    console.log(is_plural(‘octopus’) === false) console.log(is_plural(‘octopi’) === true) console.log(is_plural(‘eyebrow’) === false) console.log(is_plural(‘eyebrows’) === true) console.log(is_plural(‘child’) === false) console.log(is_plural(‘children’) === true)

    module.exports = is_plural;