動かざることバグの如し

近づきたいよ 君の理想に

英語の単数形を複数形に変換するプログラムを作成してみた

例えば「book」って投げたら「books」で返したり、「box」で投げたら「boxes」で返ってくるようなメソッド。

そもそも複数形の命名規則って?

ここが一番手こずった。今まで感覚でやってたしググっても上位のサイトが結構間違ってる。

  • 基本的には語尾に -s をつける(ex. book → books)
  • s、x、sh、ch、oのいずれかで終わる語なら -es でおわるようにする(ex. bus → buses、judge →judges)

  • 子音字 + y で終わる語なら、 y を i に変えて -es をつける(ex. lady → ladies、baby → babies)

  • 母音字 + y で終わる語なら -s をつける(ex. boy → boys、toy → toys)

  • 子音字 + o で終わる語は -es をつける。ただし他国語からの流用語はそのまま -s をつける(ex. potato → potatoes、hero → heroes、piano → pianos、photo → photos)

  • 母音字 + o で終わる語はそのまま -s をつける(ex. radio → radios、video → videos)

  • -f、-fe で終わる語はそれぞれを -ves に変えるが、他国語からの流用語はそのまま -s をつける。(ex. knife → knives、leaf → leaves、safe → safes、roof → roofs)

  • その他例外的な命名規則やそもそも複数形がないやつもある

以上が命名規則である。これをPHPで表してみる。

<?php
$dictionary = array(
    'man' => 'men',
    'seaman' => 'seamen',
    'snowman' => 'snowmen',
    'woman' => 'women',
    'person' => 'people',
    'child' => 'children',
    'foot' => 'feet',
    'crux' => 'cruces',
    'oasis' => 'oases',
    'phenomenon' => 'phenomena',
    'tooth' => 'teeth',
    'goose' => 'geese',
    'genus' => 'genera',
    'graffito' => 'graffiti',
    'mythos' => 'mythoi',
    'numen' => 'numina',
    'equipment' => 'equipment',
    'information' => 'information',
    'rice' => 'rice',
    'money' => 'money',
    'species' => 'species',
    'series' => 'series',
    'fish' => 'fish',
    'sheep' => 'sheep',
    'swiss' => 'swiss',
    'chief' => 'chiefs',
    'cliff' => 'cliffs',
    'proof' => 'proofs',
    'reef' => 'reefs',
    'relief' => 'reliefs',
    'roof' => 'roofs',
    'piano' => 'pianos',
    'photo' => 'photos',
    'safe' => 'safes',
);
function singular2plural($singular) {
    global $dictionary;
    if (array_key_exists($singular, $dictionary)) {
        $plural = $dictionary[$singular];
    } elseif (preg_match('/(a|i|u|e|o)o$/', $singular)) {
        $plural = $singular . "s";
    } elseif (preg_match('/(s|x|sh|ch|o)$/', $singular)) {
        $plural = preg_replace('/(s|x|sh|ch|o)$/', '$1es', $singular);
    } elseif (preg_match('/(b|c|d|f|g|h|j|k|l|m|n|p|q|r|s|t|v|w|x|y|z)y$/', $singular)) {
        $plural = preg_replace('/(b|c|d|f|g|h|j|k|l|m|n|p|q|r|s|t|v|w|x|y|z)y$/', '$1ies', $singular);
    } elseif (preg_match('/(f|fe)$/', $singular)) {
        $plural = preg_replace('/(f|fe)$/', 'ves', $singular);
    } else {
        $plural = $singular . "s";
    }
    return $plural;
}
$str = "book";
echo singular2plural( $str );

これで実行すると「books」と表示されるはずである。