Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Cabbit

macrumors 68020
Original poster
Jan 30, 2006
2,128
1
Scotland
Hello,

i have a regular expression array for converting singular words to plural and am trying to make a version for taking plural to singular.

Does anyone know how to do the regular expression for this.

My plural version:
PHP:
$plural = array(
			array('/(quiz)$/i',               "$1zes"   ),
			array('/^(ox)$/i',                "$1en"    ),
			array('/([m|l])ouse$/i',          	"$1ice"   	),
			array('/(matr|vert|ind)ix|ex$/i', 	"$1ices"  	),
			array('/(x|ch|ss|sh)$/i',         	"$1es"    	),
			array('/([^aeiouy]|qu)y$/i',      	"$1ies"   	),
			array('/([^aeiouy]|qu)ies$/i',    	"$1y"     	),
			array('/(hive)$/i',               	"$1s"     	),
			array('/(?:([^f])fe|([lr])f)$/i', 	"$1$2ves" 	),
			array('/sis$/i',                  	"ses"     	),
			array('/([ti])um$/i',             	"$1a"     	),
			array('/(buffal|tomat)o$/i',      	"$1oes"  	),
			array('/(bu)s$/i',                	"$1ses"   	),
			array('/(alias|status)$/i',       	"$1es"    	),
			array('/(octop|vir)us$/i',        	"$1i"     	),
			array('/(ax|test)is$/i',        	"$1es"    	),
			array('/s$/i',                    	"s"       	),
			array('/$/',                      	"s"      	)
 
Only got one left to figure out.

PHP:
array('/(?:([^f])fe|([lr])f)$/i', 			"$1$2ves" 	),
 
I recommend that you put another array right before the line for "ox", to handle "child"/"children".

The full class handles things like that both ways.

This is the full class
PHP:
namespace Cabbit;
class String
{
	public static function conditionallyString($string, $count)
	{
		if (intval($count) !== 0)
		
		return String::toPlural($string);
		return $string; 
	}
	
	public static function startsWithUpperCase($string) 
	{
    	$char = mb_substr ($string, 0, 1, "UTF-8");
    	return mb_strtolower($char, "UTF-8") != $char;
	}
		
	public static function toPlural($string) 
	{
		$plural = array(
			array('/(quiz)$/i',               "$1zes"   ),
			array('/^(ox)$/i',                "$1en"    ),
			array('/([m|l])ouse$/i',          "$1ice"   ),
			array('/(matr|vert|ind)ix|ex$/i', "$1ices"  ),
			array('/(x|ch|ss|sh)$/i',         "$1es"    ),
			array('/([^aeiouy]|qu)y$/i',      "$1ies"   ),
			array('/([^aeiouy]|qu)ies$/i',    "$1y"     ),
			array('/(hive)$/i',               "$1s"     ),
			array('/(?:([^f])fe|([lr])f)$/i', "$1$2ves" ),
			array('/sis$/i',                  "ses"     ),
			array('/([ti])um$/i',             "$1a"     ),
			array('/(buffal|tomat)o$/i',      "$1oes"   ),
			array('/(bu)s$/i',                "$1ses"   ),
			array('/(alias|status)$/i',       "$1es"    ),
			array('/(octop|vir)us$/i',        "$1i"     ),
			array('/(ax|test)is$/i',          "$1es"    ),
			array('/s$/i',                    "s"       ),
			array('/$/',                      "s"       )
		);
		
		$irregular = array(
			array('move',   	'moves'),
			array('sex',    	'sexes'),
			array('child',  	'children'),
			array('man',    	'men'),
			array('person', 	'people'),
			array('alumnus', 	'alumni'),
			array('focus', 		'focuses'),
			array('cactus', 	'cacti'),
			array('fungus', 	'fungi'),
			array('nucleus', 	'nuclei'),
			array('radius', 	'radii'),
			array('stimulus', 	'stimuli'),
			array('appendix', 	'appendices'),
			array('beau', 		'beaux'),
			array('woman', 		'women'),
			array('corpus',		'corpora'),
			array('criterion',	'criteria'),
			array('curriculum',	'curricula'),
			array('genus',		'genera'),
			array('memorandum',	'memoranda'),
			array('phenomenon',	'phenomena'),
			array('foot', 		'feet'),
			array('goose', 		'geese'),
			array('tooth',		'teeth'),
			array('antenna',	'antennae'),
			array('formula',	'formulae'),
			array('nebula',		'nebulae'),
			array('vertebra',	'vertebrae'),
			array('vita',		'vitae')
		);
		
		$uncountable = array( 
			'sheep', 
			'fish',
			'series',
			'species',
			'money',
			'rice',
			'information',
			'equipment',
			'deer',
			'means',
			'offspring',
			'series'
		);
		
		// Save some time in the case that singular and plural are the same
		if (in_array(strtolower($string), $uncountable))
			return $string;
		
		// Check for irregular singular forms
		foreach ($irregular as $noun)
		{
			if (strtolower($string) == $noun[0])
			{
				if (String::startsWithUpperCase($string))
				{
					// Returns the string with the first letter in uppercase
					return ucwords($noun[1]);
				}
				else
				{
					// Returns the string with the first letter in lowercase
					return $noun[1];
				}			
			}
		}
		
		// Check for matches using regular expressions
		foreach ($plural as $pattern)
		{
			if ( preg_match($pattern[0], $string))
			return preg_replace($pattern[0], $pattern[1], $string);
		}
		
		return $string;
	}
	
	public static function toSingular($string)
	{
			$singluar = array(
			array('/(quizzes)$/i',             			"quiz"   	),
			array('/^(oxen)$/i',                		"ox"    	),
			array('/([m|l])ice$/i',          			"$1ouse"   	),
			array('/(ind)ices$/i',          			"$1ex"   	),
			array('/(matr|vert)ices$/i', 				"$1ix"  	),
			array('/(x|ch|ss|sh)es$/i',         		"$1"    	),
			array('/([^aeiouy]|qu)ies$/i',    			"$1y"     	),
			array('/(hive)s$/i',               			"$1"     	),
			array('/ses$/i',                  			"sis"     	),
			array('/([ti])a$/i',             			"$1um"     	),
			array('/(buffal|tomat)oes$/i',      		"$1o"  		),
			array('/(bu)ses$/i',                		"$1s"   	),
			array('/(alias|status)es$/i',       		"$1"    	),
			array('/(octop|vir)i$/i',        			"$1us"     	),
			array('/(ax|test)es$/i',        			"$1is"    	),
			array('/s$/i',                    			""       	),
			array('/$/',                      			""      	)
		);
		
		$irregular = array(
			array('moves', 		'move'),
			array('sexes', 		'sex'),
			array('children',  	'child'),
			array('men',    	'man'),
			array('people', 	'person'),
			array('alumni',		'alumnus' ),
			array('focuses',	'focus'),
			array('cacti',		'cactus'),
			array('fungi',		'fungus'),
			array('nuclei',		'nucleus'),
			array('radii',		'radius'),
			array('stimuli', 	'stimulus'),
			array('appendices',	'appendix'),
			array('beaux',		'beau'),
			array('women',		'woman'),
			array('corpora',	'corpus'),
			array('criteria',	'criterion'),
			array('curricula',	'curriculum'),
			array('genera',		'genus'),
			array('memoranda',	'memorandum'),
			array('phenomena',	'phenomenon'),
			array('feet',		'foot'),
			array('geese',		'goose'),
			array('teeth',		'tooth'),
			array('antennae',	'antenna'),
			array('formulae',	'formula'),
			array('nebulae',	'nebula'),
			array('vertebrae',	'vertebra'),
			array('vitae',		'vita')
		);
		
		$uncountable = array( 
			'sheep', 
			'fish',
			'series',
			'species',
			'money',
			'rice',
			'information',
			'equipment',
			'deer',
			'means',
			'offspring',
			'series'
		);
		
		// Save some time in the case that singular and plural are the same
		if (in_array(strtolower($string), $uncountable))
			return $string;
		
		// Check for irregular singular forms
		foreach ($irregular as $noun)
		{
			if (strtolower($string) == $noun[0])
			{
				if (String::startsWithUpperCase($string))
				{
					// Returns the string with the first letter in uppercase
					return ucwords($noun[1]);
				}
				else
				{
					// Returns the string with the first letter in lowercase
					return $noun[1];
				}			
			}
		}
		
		// Check for matches using regular expressions
		foreach ($singluar as $pattern)
		{
			if ( preg_match($pattern[0], $string))
			return preg_replace($pattern[0], $pattern[1], $string);
		}
		
		
		return $string;
	}
}
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.