Skip to content

Instantly share code, notes, and snippets.

@effone
Last active October 28, 2021 02:48
Show Gist options
  • Save effone/1e54f364559bf919af3be97b7f9d94af to your computer and use it in GitHub Desktop.
Save effone/1e54f364559bf919af3be97b7f9d94af to your computer and use it in GitHub Desktop.
Plural Literature Suffix
<?php
// To extend $key => $value pairs further as exception gets identified
return array(
'addendum'=>'addenda',
'analysis'=>'analyses',
'child'=>'children',
'goose'=>'geese',
'locus'=>'loci',
'louse'=>'lice',
'oasis'=>'oases',
'ovum'=>'ova',
'man'=>'men',
'mouse'=>'mice',
'tooth'=>'teeth',
'woman'=>'women'
);
<?php
function plural($word = '', $count=0, $return_count = 0)
// Example:
// echo plural('boy', 0); // 'boy'
// echo plural('mango', 2); // 'mangoes'
// echo plural('knife', 3, 1); // '3 knives'
// Limitation: can't convert to plural out of rules, like man : men / to handle this exception list is being used.
{
/*
General Plural Literature Suffix Rules:
[1.0] 'ies' rule (ends in a consonant + y : baby/lady)
[2.0] 'ves' rule (ends in f or fe : leaf/knife) --- roof : rooves (correct but old english, roofs is ok).
[3.1] 'es' rule 1 (ends in a consonant + o : volcano/mango)
[3.2] 'es' rule 2 (ends in ch, sh, s, ss, x, z : match/dish/bus/glass/fox/buzz)
[4.1] 's' rule 1 (ends in a vowel + y or o : boy/radio)
[4.2] 's' rule 2 (ends in other than above : cat/ball)
*/
# Use mb_substr for multibyte #
// Normalize case, not even first letter plural as a number supposed to be placed before
$word = strtolower(trim($word));
// Define vowels, all non-vowel is consonant
$vowel = array('a','e','i','o','u');
// Prefix count with word, if specified
if (preg_match('/^[A-Za-z]{2,}$/', $word)) // a noun should be 2 or more letter
{
if($count > 1)
{
$excep = include('pluralexcep.php'); // Load exception list
if(array_key_exists($word, $excep))
{
$word = $excep[$word];
}
else if(!in_array(substr($word,-2,1), $vowel) && substr($word,-1)==='y') // Rule [1.0]
{
$word = rtrim($word,'y').'ies';
}
else if(substr($word,-1)==='f' || substr($word,-2,2)==='fe') // Rule [2.0]
{
$word = (substr($word,-1)==='e') ? substr($word, 0, -2) : substr($word, 0, -1);
$word = $word.'ves';
}
else if((!in_array(substr($word,-2,1), $vowel) && substr($word,-1)==='o') // Rule [3.1]
|| in_array(substr($word,-2,2), ['ch','sh','ss']) || in_array(substr($word,-1), ['s','x','z'])) // Rule [3.2]
{
$word = $word.'es';
}
else
{ // Rule [4.2], covering [4.1]
$word = $word.'s';
}
} else if ($count < 0){
return false; // No negate in real world object existance !!??
}
if(!empty($return_count)) $word = $count.' '.$word;
return $word;
}
return false;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment