2017-03-01 64 views
-1

我试图解决使用PHP转换为拉丁文的问题。我被卡住了,因为根据上下文的不同,Y既可以是元音也可以是辅音。如果Y在单词的开头,则被认为是辅音,如果它在中间被认为是元音。PHP猪拉丁语,Y既作为元音和辅音

例如“黄色风格”变成“ellowyay ylestay”。规则是:“以元音开始的单词(A,E,I,O,U)只在单词的末尾添加”WAY“。 以辅音开头的单词具有所有辅音字母第一个元音移到了单词的末尾(而不是第一个辅音字母),并且附加了“AY”(在这种情况下,'Y'被计算为元音)“

我的代码如下:

class Config{ 

public static $vowels = 'aeiou'; 
public static $vowelTermination = "way"; 
public static $consonants = 'b-df-hj-np-tv-z'; 
} 

class Piglatin 
{ 

public function convert($input) 
{ 
    $return = ""; 
    $wordArray = explode(" ", $input); 

    foreach($wordArray as $word){ 
     $return .= $this->translate($word); 
     $return .= " "; 
    } 

    return rtrim($return); 
} 

public function translate($input) 
{ 
    $translation = ""; 

    if(!empty($input)){ 

     if(is_numeric($input)){ 
      return $input; 
     } 

     if($this->startVowel($input)){ 
      $input = $input . Config::$vowelTermination; 
      return $input; 
     } 

     if($this->startConsonant($input) && strlen($input)===1){ 
      return $input.'ay'; 
     } 

     if($this->startConsonant($input)){ 
      $input = preg_replace('/^([b-df-hj-np-tv-xz]*)([aeiouy].*)$/', "$2$1ay", $input); 
      return $input; 
     } 
    } 

    return $translation; 
} 

public function startVowel($input) 
{ 
    $regex = '/^['.Config::$vowels.']/i'; 

    if(preg_match($regex, $input)){ 
     return true; 
    } 
    return false; 
} 

public function startConsonant($input) 
{ 
    $regex = '/^['.Config::$consonants.']/i'; 

    if(preg_match($regex, $input)){ 
     return true; 
    } 
    return false; 
} 
} 

其中给定输入“黄色风格”会产生接近预期结果但不完全的“黄色ylestay”。

关于如何解决这个问题的任何想法?

+2

见https://github.com/davidyell/Pig -Latin-Translator/blob/master/lib/translate.php –

+2

上面你说:'例如“黄色风格”变成“ellowyay ylestay”。规则是:'。在底部,你说:'哪个给定的输入“黄色风格”产生“ellowyay ylestay”这是接近预期的结果,但不完全' – sln

+0

不重复,但存在于github:D @WiktorStribiżew – MohaMad

回答

0

preg_replace中的正则表达式与第一个捕获组中的Y不匹配:([b-df-hj-np-tv-xz]*)。所以这些组最终为$1=''$2='yellow',因此结果是yelloway

我没有测试过,但这应该工作,不是吗?

preg_replace('/^([b-df-hj-np-tv-z]*)([aeiouy].*)$/', "$2$1ay", $input) 
+0

通过这种方式,他不再考虑字母中间的Y作为元音。例如,我现在得到的是“ellowyay estylay”而不是“ellowyay ylestay”,whoch是预期的结果。 –

1

对我来说,你有3个单独的条件。
这个正则表达式使用分支重置(并行组)与这些条件。
必须强制执行每个条件,这就是它的作用。

请注意,它不计算边界,但如果您需要,我会使用空白边界。 (?<!\S)(?: regex)(?!\S)
此外,您还可以其他字符[b-df-hj-np-tv-xz]
但不能添加到[a-z]类或元音类[aeiouy][y]类。

基本上它是
查找(?i)(?|([aeiou][a-z]*)()|([b-df-hj-np-tv-xz]+)([aeiouy][a-z]*)|([y]+[b-df-hj-np-tv-xz]*)([aeiouy][a-z]*))
更换$2$1ay

扩展

(?i)        # Modifier - case independent 
(?|        # Branch Reset 
     ([aeiou] [a-z]*)    # (1), Condition: starts with a vowel 
     ()        # (2) 
    | 
     ([b-df-hj-np-tv-xz]+)   # (1), Condition: starts with a non-Y consonant 
     ([aeiouy] [a-z]*)    # (2), and Y as vowel 
    | 
     ([y]+ [b-df-hj-np-tv-xz]*)  # (1), Condition: starts with a Y consonant 
     ([aeiouy] [a-z]*)    # (2), and Y as vowel 
) 

样品输入yellow style atak yyerto yystay start
样本输出ellowyay ylestay atakay ertoyyay ayyystay artstay

+0

它总是有意义的。将尽快尝试。 –

+0

@CláudioRibeiro - 你解决了什么问题? – sln