Вход Регистрация
Файл: vendor/symfony/string/Inflector/EnglishInflector.php
Строк: 375
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace SymfonyComponentStringInflector;

final class 
EnglishInflector implements InflectorInterface
{
    
/**
     * Map English plural to singular suffixes.
     *
     * @see http://english-zone.com/spelling/plurals.html
     */
    
private const PLURAL_MAP = [
        
// First entry: plural suffix, reversed
        // Second entry: length of plural suffix
        // Third entry: Whether the suffix may succeed a vowel
        // Fourth entry: Whether the suffix may succeed a consonant
        // Fifth entry: singular suffix, normal

        // bacteria (bacterium)
        
['airetcab'8truetrue'bacterium'],

        
// corpora (corpus)
        
['aroproc'7truetrue'corpus'],

        
// criteria (criterion)
        
['airetirc'8truetrue'criterion'],

        
// curricula (curriculum)
        
['alucirruc'9truetrue'curriculum'],

        
// quora (quorum)
        
['arouq'5truetrue'quorum'],

        
// genera (genus)
        
['areneg'6truetrue'genus'],

        
// media (medium)
        
['aidem'5truetrue'medium'],

        
// memoranda (memorandum)
        
['adnaromem'9truetrue'memorandum'],

        
// phenomena (phenomenon)
        
['anemonehp'9truetrue'phenomenon'],

        
// strata (stratum)
        
['atarts'6truetrue'stratum'],

        
// nebulae (nebula)
        
['ea'2truetrue'a'],

        
// services (service)
        
['secivres'8truetrue'service'],

        
// mice (mouse), lice (louse)
        
['eci'3falsetrue'ouse'],

        
// geese (goose)
        
['esee'4falsetrue'oose'],

        
// fungi (fungus), alumni (alumnus), syllabi (syllabus), radii (radius)
        
['i'1truetrue'us'],

        
// men (man), women (woman)
        
['nem'3truetrue'man'],

        
// children (child)
        
['nerdlihc'8truetrue'child'],

        
// oxen (ox)
        
['nexo'4falsefalse'ox'],

        
// indices (index), appendices (appendix), prices (price)
        
['seci'4falsetrue, ['ex''ix''ice']],

        
// codes (code)
        
['sedoc'5falsetrue'code'],

        
// selfies (selfie)
        
['seifles'7truetrue'selfie'],

        
// zombies (zombie)
        
['seibmoz'7truetrue'zombie'],

        
// movies (movie)
        
['seivom'6truetrue'movie'],

        
// names (name)
        
['seman'5truefalse'name'],

        
// conspectuses (conspectus), prospectuses (prospectus)
        
['sesutcep'8truetrue'pectus'],

        
// feet (foot)
        
['teef'4truetrue'foot'],

        
// geese (goose)
        
['eseeg'5truetrue'goose'],

        
// teeth (tooth)
        
['hteet'5truetrue'tooth'],

        
// news (news)
        
['swen'4truetrue'news'],

        
// series (series)
        
['seires'6truetrue'series'],

        
// babies (baby)
        
['sei'3falsetrue'y'],

        
// accesses (access), addresses (address), kisses (kiss)
        
['sess'4truefalse'ss'],

        
// statuses (status)
        
['sesutats'8truetrue'status'],

        
// article (articles), ancle (ancles)
        
['sel'3truetrue'le'],

        
// analyses (analysis), ellipses (ellipsis), fungi (fungus),
        // neuroses (neurosis), theses (thesis), emphases (emphasis),
        // oases (oasis), crises (crisis), houses (house), bases (base),
        // atlases (atlas)
        
['ses'3truetrue, ['s''se''sis']],

        
// objectives (objective), alternative (alternatives)
        
['sevit'5truetrue'tive'],

        
// drives (drive)
        
['sevird'6falsetrue'drive'],

        
// lives (life), wives (wife)
        
['sevi'4falsetrue'ife'],

        
// moves (move)
        
['sevom'5truetrue'move'],

        
// hooves (hoof), dwarves (dwarf), elves (elf), leaves (leaf), caves (cave), staves (staff)
        
['sev'3truetrue, ['f''ve''ff']],

        
// axes (axis), axes (ax), axes (axe)
        
['sexa'4falsefalse, ['ax''axe''axis']],

        
// indexes (index), matrixes (matrix)
        
['sex'3truefalse'x'],

        
// quizzes (quiz)
        
['sezz'4truefalse'z'],

        
// bureaus (bureau)
        
['suae'4falsetrue'eau'],

        
// fees (fee), trees (tree), employees (employee)
        
['see'3truetrue'ee'],

        
// edges (edge)
        
['segd'4truetrue'dge'],

        
// roses (rose), garages (garage), cassettes (cassette),
        // waltzes (waltz), heroes (hero), bushes (bush), arches (arch),
        // shoes (shoe)
        
['se'2truetrue, ['''e']],

        
// status (status)
        
['sutats'6truetrue'status'],

        
// tags (tag)
        
['s'1truetrue''],

        
// chateaux (chateau)
        
['xuae'4falsetrue'eau'],

        
// people (person)
        
['elpoep'6truetrue'person'],
    ];

    
/**
     * Map English singular to plural suffixes.
     *
     * @see http://english-zone.com/spelling/plurals.html
     */
    
private const SINGULAR_MAP = [
        
// First entry: singular suffix, reversed
        // Second entry: length of singular suffix
        // Third entry: Whether the suffix may succeed a vowel
        // Fourth entry: Whether the suffix may succeed a consonant
        // Fifth entry: plural suffix, normal

        // axes (axis)
        
['sixa'4falsefalse'axes'],

        
// criterion (criteria)
        
['airetirc'8falsefalse'criterion'],

        
// nebulae (nebula)
        
['aluben'6falsefalse'nebulae'],

        
// children (child)
        
['dlihc'5truetrue'children'],

        
// prices (price)
        
['eci'3falsetrue'ices'],

        
// services (service)
        
['ecivres'7truetrue'services'],

        
// lives (life), wives (wife)
        
['efi'3falsetrue'ives'],

        
// selfies (selfie)
        
['eifles'6truetrue'selfies'],

        
// movies (movie)
        
['eivom'5truetrue'movies'],

        
// lice (louse)
        
['esuol'5falsetrue'lice'],

        
// mice (mouse)
        
['esuom'5falsetrue'mice'],

        
// geese (goose)
        
['esoo'4falsetrue'eese'],

        
// houses (house), bases (base)
        
['es'2truetrue'ses'],

        
// geese (goose)
        
['esoog'5truetrue'geese'],

        
// caves (cave)
        
['ev'2truetrue'ves'],

        
// drives (drive)
        
['evird'5falsetrue'drives'],

        
// objectives (objective), alternative (alternatives)
        
['evit'4truetrue'tives'],

        
// moves (move)
        
['evom'4truetrue'moves'],

        
// staves (staff)
        
['ffats'5truetrue'staves'],

        
// hooves (hoof), dwarves (dwarf), elves (elf), leaves (leaf)
        
['ff'2truetrue'ffs'],

        
// hooves (hoof), dwarves (dwarf), elves (elf), leaves (leaf)
        
['f'1truetrue, ['fs''ves']],

        
// arches (arch)
        
['hc'2truetrue'ches'],

        
// bushes (bush)
        
['hs'2truetrue'shes'],

        
// teeth (tooth)
        
['htoot'5truetrue'teeth'],

        
// albums (album)
        
['mubla'5truetrue'albums'],

        
// quorums (quorum)
        
['murouq'6truetrue, ['quora''quorums']],

        
// bacteria (bacterium), curricula (curriculum), media (medium), memoranda (memorandum), phenomena (phenomenon), strata (stratum)
        
['mu'2truetrue'a'],

        
// men (man), women (woman)
        
['nam'3truetrue'men'],

        
// people (person)
        
['nosrep'6truetrue, ['persons''people']],

        
// criteria (criterion)
        
['noiretirc'9truetrue'criteria'],

        
// phenomena (phenomenon)
        
['nonemonehp'10truetrue'phenomena'],

        
// echoes (echo)
        
['ohce'4truetrue'echoes'],

        
// heroes (hero)
        
['oreh'4truetrue'heroes'],

        
// atlases (atlas)
        
['salta'5truetrue'atlases'],

        
// aliases (alias)
        
['saila'5truetrue'aliases'],

        
// irises (iris)
        
['siri'4truetrue'irises'],

        
// analyses (analysis), ellipses (ellipsis), neuroses (neurosis)
        // theses (thesis), emphases (emphasis), oases (oasis),
        // crises (crisis)
        
['sis'3truetrue'ses'],

        
// accesses (access), addresses (address), kisses (kiss)
        
['ss'2truefalse'sses'],

        
// syllabi (syllabus)
        
['suballys'8truetrue'syllabi'],

        
// buses (bus)
        
['sub'3truetrue'buses'],

        
// circuses (circus)
        
['suc'3truetrue'cuses'],

        
// hippocampi (hippocampus)
        
['supmacoppih'11falsefalse'hippocampi'],

        
// campuses (campus)
        
['sup'3truetrue'puses'],

        
// status (status)
        
['sutats'6truetrue, ['status''statuses']],

        
// conspectuses (conspectus), prospectuses (prospectus)
        
['sutcep'6truetrue'pectuses'],

        
// fungi (fungus), alumni (alumnus), syllabi (syllabus), radii (radius)
        
['su'2truetrue'i'],

        
// news (news)
        
['swen'4truetrue'news'],

        
// feet (foot)
        
['toof'4truetrue'feet'],

        
// chateaux (chateau), bureaus (bureau)
        
['uae'3falsetrue, ['eaus''eaux']],

        
// oxen (ox)
        
['xo'2falsefalse'oxen'],

        
// hoaxes (hoax)
        
['xaoh'4truefalse'hoaxes'],

        
// indices (index)
        
['xedni'5falsetrue, ['indicies''indexes']],

        
// fax (faxes, faxxes)
        
['xaf'3truetrue, ['faxes''faxxes']],

        
// boxes (box)
        
['xo'2falsetrue'oxes'],

        
// indexes (index), matrixes (matrix), appendices (appendix)
        
['x'1truefalse, ['ces''xes']],

        
// babies (baby)
        
['y'1falsetrue'ies'],

        
// quizzes (quiz)
        
['ziuq'4truefalse'quizzes'],

        
// waltzes (waltz)
        
['z'1truetrue'zes'],
    ];

    
/**
     * A list of words which should not be inflected, reversed.
     */
    
private const UNINFLECTED = [
        
'',

        
// data
        
'atad',

        
// deer
        
'reed',

        
// equipment
        
'tnempiuqe',

        
// feedback
        
'kcabdeef',

        
// fish
        
'hsif',

        
// health
        
'htlaeh',

        
// history
        
'yrotsih',

        
// info
        
'ofni',

        
// information
        
'noitamrofni',

        
// money
        
'yenom',

        
// moose
        
'esoom',

        
// series
        
'seires',

        
// sheep
        
'peehs',

        
// species
        
'seiceps',

        
// traffic
        
'ciffart',

        
// aircraft
        
'tfarcria',

        
// hardware
        
'erawdrah',
    ];

    public function 
singularize(string $plural): array
    {
        
$pluralRev strrev($plural);
        
$lowerPluralRev strtolower($pluralRev);
        
$pluralLength strlen($lowerPluralRev);

        
// Check if the word is one which is not inflected, return early if so
        
if (in_array($lowerPluralRevself::UNINFLECTEDtrue)) {
            return [
$plural];
        }

        
// The outer loop iterates over the entries of the plural table
        // The inner loop $j iterates over the characters of the plural suffix
        // in the plural table to compare them with the characters of the actual
        // given plural suffix
        
foreach (self::PLURAL_MAP as $map) {
            
$suffix $map[0];
            
$suffixLength $map[1];
            
$j 0;

            
// Compare characters in the plural table and of the suffix of the
            // given plural one by one
            
while ($suffix[$j] === $lowerPluralRev[$j]) {
                
// Let $j point to the next character
                
++$j;

                
// Successfully compared the last character
                // Add an entry with the singular suffix to the singular array
                
if ($j === $suffixLength) {
                    
// Is there any character preceding the suffix in the plural string?
                    
if ($j $pluralLength) {
                        
$nextIsVowel str_contains('aeiou'$lowerPluralRev[$j]);

                        if (!
$map[2] && $nextIsVowel) {
                            
// suffix may not succeed a vowel but next char is one
                            
break;
                        }

                        if (!
$map[3] && !$nextIsVowel) {
                            
// suffix may not succeed a consonant but next char is one
                            
break;
                        }
                    }

                    
$newBase substr($plural0$pluralLength $suffixLength);
                    
$newSuffix $map[4];

                    
// Check whether the first character in the plural suffix
                    // is uppercased. If yes, uppercase the first character in
                    // the singular suffix too
                    
$firstUpper ctype_upper($pluralRev[$j 1]);

                    if (
is_array($newSuffix)) {
                        
$singulars = [];

                        foreach (
$newSuffix as $newSuffixEntry) {
                            
$singulars[] = $newBase.($firstUpper ucfirst($newSuffixEntry) : $newSuffixEntry);
                        }

                        return 
$singulars;
                    }

                    return [
$newBase.($firstUpper ucfirst($newSuffix) : $newSuffix)];
                }

                
// Suffix is longer than word
                
if ($j === $pluralLength) {
                    break;
                }
            }
        }

        
// Assume that plural and singular is identical
        
return [$plural];
    }

    public function 
pluralize(string $singular): array
    {
        
$singularRev strrev($singular);
        
$lowerSingularRev strtolower($singularRev);
        
$singularLength strlen($lowerSingularRev);

        
// Check if the word is one which is not inflected, return early if so
        
if (in_array($lowerSingularRevself::UNINFLECTEDtrue)) {
            return [
$singular];
        }

        
// The outer loop iterates over the entries of the singular table
        // The inner loop $j iterates over the characters of the singular suffix
        // in the singular table to compare them with the characters of the actual
        // given singular suffix
        
foreach (self::SINGULAR_MAP as $map) {
            
$suffix $map[0];
            
$suffixLength $map[1];
            
$j 0;

            
// Compare characters in the singular table and of the suffix of the
            // given plural one by one

            
while ($suffix[$j] === $lowerSingularRev[$j]) {
                
// Let $j point to the next character
                
++$j;

                
// Successfully compared the last character
                // Add an entry with the plural suffix to the plural array
                
if ($j === $suffixLength) {
                    
// Is there any character preceding the suffix in the plural string?
                    
if ($j $singularLength) {
                        
$nextIsVowel str_contains('aeiou'$lowerSingularRev[$j]);

                        if (!
$map[2] && $nextIsVowel) {
                            
// suffix may not succeed a vowel but next char is one
                            
break;
                        }

                        if (!
$map[3] && !$nextIsVowel) {
                            
// suffix may not succeed a consonant but next char is one
                            
break;
                        }
                    }

                    
$newBase substr($singular0$singularLength $suffixLength);
                    
$newSuffix $map[4];

                    
// Check whether the first character in the singular suffix
                    // is uppercased. If yes, uppercase the first character in
                    // the singular suffix too
                    
$firstUpper ctype_upper($singularRev[$j 1]);

                    if (
is_array($newSuffix)) {
                        
$plurals = [];

                        foreach (
$newSuffix as $newSuffixEntry) {
                            
$plurals[] = $newBase.($firstUpper ucfirst($newSuffixEntry) : $newSuffixEntry);
                        }

                        return 
$plurals;
                    }

                    return [
$newBase.($firstUpper ucfirst($newSuffix) : $newSuffix)];
                }

                
// Suffix is longer than word
                
if ($j === $singularLength) {
                    break;
                }
            }
        }

        
// Assume that plural is singular with a trailing `s`
        
return [$singular.'s'];
    }
}
Онлайн: 3
Реклама