1

重複の可能性:
オブジェクトを「a」または「an」のどちらで記述するかをプログラムで決定しますか?

次のような文を出力する必要があります。

Are you An American?

または:

Are you A German?

私は国名を持っていますが、その国名の正しい冠詞AまたはAnを見つける必要があります。

ここに記載されているすべての例外を除いて、その文法規則を実装するphpライブラリ/ユーティリティ関数はありますか?Zend_Localeについて考えましたが、適切なものが見つかりませんでした。

私もグーグルで検索しましたが、「AvsAnPHP」の結果はあまり役に立ちません。

4

4 に答える 4

8

ある程度使用可能なソリューションについては、この回答を参照してください。Lingua::EN::Inflect回答には、使用する不定冠詞を決定する上でかなり良い仕事をしているように見える Perl モジュールからの抜粋が含まれています。

A("cat")        # -> "a cat"
AN("cat")       # -> "a cat"
A("euphemism")      # -> "a euphemism"
A("Euler number")   # -> "an Euler number"
A("hour")       # -> "an hour"
A("houri")      # -> "a houri"

ルールは正規表現として定義されているため、PHP への移植はそれほど難しくありません。

編集:これをPHPに変換することになりました( githubでも利用可能)。

使用法:print IndefiniteArticle::A("umbrella"); // an umbrella

<?php

class IndefiniteArticle
{

    public static function AN($input, $count=1) {
        return self::A($input, $count);
    }

    public static function A($input, $count=1) {
        $matches = array();
        $matchCount = preg_match("/\A(\s*)(?:an?\s+)?(.+?)(\s*)\Z/i", $input, $matches);
        list($all, $pre, $word, $post) = $matches;
        if(!$word)
            return $input;
        $result = self::_indef_article($word, $count);  
                return $pre.$result.$post;
    }

    # THIS PATTERN MATCHES STRINGS OF CAPITALS STARTING WITH A "VOWEL-SOUND"
    # CONSONANT FOLLOWED BY ANOTHER CONSONANT, AND WHICH ARE NOT LIKELY
    # TO BE REAL WORDS (OH, ALL RIGHT THEN, IT'S JUST MAGIC!)

    private static $A_abbrev = "(?! FJO | [HLMNS]Y.  | RY[EO] | SQU
          | ( F[LR]? | [HL] | MN? | N | RH? | S[CHKLMNPTVW]? | X(YL)?) [AEIOU])
            [FHLMNRSX][A-Z]
        ";

    # THIS PATTERN CODES THE BEGINNINGS OF ALL ENGLISH WORDS BEGINING WITH A
    # 'y' FOLLOWED BY A CONSONANT. ANY OTHER Y-CONSONANT PREFIX THEREFORE
    # IMPLIES AN ABBREVIATION.

    private static $A_y_cons = 'y(b[lor]|cl[ea]|fere|gg|p[ios]|rou|tt)';

    # EXCEPTIONS TO EXCEPTIONS

    private static $A_explicit_an = "euler|hour(?!i)|heir|honest|hono";

    private static $A_ordinal_an = "[aefhilmnorsx]-?th";

    private static $A_ordinal_a = "[bcdgjkpqtuvwyz]-?th";

    private static function _indef_article($word, $count) {
        if($count != 1) // TODO: Check against $PL_count_one instead
            return "$count $word";

            # HANDLE USER-DEFINED VARIANTS
        // TODO


        # HANDLE ORDINAL FORMS
        if(preg_match("/^(".self::$A_ordinal_a.")/i", $word))       return "a $word";
        if(preg_match("/^(".self::$A_ordinal_an.")/i", $word))      return "an $word";

        # HANDLE SPECIAL CASES

        if(preg_match("/^(".self::$A_explicit_an.")/i", $word))         return "an $word";
        if(preg_match("/^[aefhilmnorsx]$/i", $word))        return "an $word";
        if(preg_match("/^[bcdgjkpqtuvwyz]$/i", $word))      return "a $word";

            # HANDLE ABBREVIATIONS

        if(preg_match("/^(".self::$A_abbrev.")/x", $word))          return "an $word";
        if(preg_match("/^[aefhilmnorsx][.-]/i", $word))         return "an $word";
        if(preg_match("/^[a-z][.-]/i", $word))          return "a $word";

        # HANDLE CONSONANTS

        if(preg_match("/^[^aeiouy]/i", $word))                  return "a $word";

            # HANDLE SPECIAL VOWEL-FORMS

        if(preg_match("/^e[uw]/i", $word))                      return "a $word";
        if(preg_match("/^onc?e\b/i", $word))                    return "a $word";
        if(preg_match("/^uni([^nmd]|mo)/i", $word))     return "a $word";
        if(preg_match("/^ut[th]/i", $word))                     return "an $word";
        if(preg_match("/^u[bcfhjkqrst][aeiou]/i", $word))   return "a $word";

            # HANDLE SPECIAL CAPITALS

        if(preg_match("/^U[NK][AIEO]?/", $word))                return "a $word";

        # HANDLE VOWELS

        if(preg_match("/^[aeiou]/i", $word))            return "an $word";

        # HANDLE y... (BEFORE CERTAIN CONSONANTS IMPLIES (UNNATURALIZED) "i.." SOUND)

        if(preg_match("/^(".self::$A_y_cons.")/i", $word))      return "an $word";

        # OTHERWISE, GUESS "a"
        return "a $word";
    }
}
于 2012-10-09T11:09:06.550 に答える
0

自分でロールするのは非常に簡単です:

function an($str) {

    $vowels = "aeiou";

    if (strpos($vowels, strtolower(substr($str, 0, 1))) !== false) {

        return "An " . $str;

    }
    else {

        return "A " . $str;

    }

}

基本的に、母音で始まる場合は「An」を使用し、それ以外の場合は「A」を使用します。

これが当てはまらないエッジケースがいくつかあるかもしれませんが、頭のてっぺんは思いつきません。見つかった場合は、一般的なテストを行う前に明示的にテストします。

function an($str) {

    if ($str == "foobarbaz") {

        return "An";

    }

    $vowels = "aeiou";

    if (strpos($vowels, strtolower(substr($str, 0, 1))) !== false) {

        return "An " . $str;

    }
    else {

        return "A " . $str;

    }

} 
于 2012-10-09T10:47:13.273 に答える
-2

これを試してください:-

$vowel_arr=array('a','e','i','o','u');
$string="America";
$len=strtolower(substr($string,0,1));

if(in_array($len,$vowel_arr))
  $pre = "an";
else
  $pre = "a";


 echo  $pre." ".$string;
于 2012-10-09T10:45:36.963 に答える
-2

非常に単純な関数を作成することをお勧めします。

この関数は国名をパラメーターとして取り、最初の文字を調べます。文字がこの配列からのものである場合

$an_char_array = array('a', 'e', 'i', 'o');

そうでなければあなたはreturn "an {$country}";そうするでしょうreturn "a {$country}";

最初に例外を考えて処理し、次に一般的な部分を実行する必要があります。

関数は次のようになります。

function prependAricle($word) {
    // handle exceptions here, e.g.:
    $an_exceptions = array('umbrella'/*, ...*/);
    $a_exceptions = array('pity'/*, ...*/);
    if(in_array(strtolower($word), $an_exceptions))
        return "an {$word}";
    if(in_array(strtolower($word), $a_exceptions))
        return "a {$word}";

    // handle general rule
    $an_char_array = array('a', 'e', 'i', 'o', 'A', 'E', 'I', 'O');
    if(in_array(substr($word, 0, 1), $an_char_array))
        return "an {$word}";
    else
        return "a {$word}";
}
于 2012-10-09T10:49:19.587 に答える