Guest

DoubleMetaphone Algorithm

By: a guest on Dec 15th, 2011  |  syntax: PHP  |  size: 31.42 KB  |  hits: 12  |  expires: Never
download  |  raw  |  embed  |  report abuse
Copied
  1. <?php
  2. class Dm
  3. {
  4.     public static function search($string, $start, $length, $needles, $mode = true)
  5.     {
  6.         $treffer = false;
  7.         $fails = 0;
  8.         foreach ($needles AS $needle) {
  9.             if ($mode == true) {
  10.                 if (substr($string, $start, $length) == $needle) {
  11.                     $treffer = true;
  12.                 }
  13.             } else {
  14.                 if (substr($string, $start, $length) != $needle) {
  15.                     $treffer = true;
  16.                 } else {
  17.                     $fails++;
  18.                 }
  19.             }
  20.         }
  21.         if ($treffer == true && $fails == 0) {
  22.             return true;
  23.         }
  24.         return false;
  25.     }
  26.  
  27.     public static function convert($st)
  28.     {
  29.         // Initial
  30.         $length = 0;
  31.         $first = 0;
  32.         $last = 0;
  33.         $pos = 0;
  34.         $prevpos = 0;
  35.         $isSlavoGermanic = 0;
  36.         $pri = '';
  37.         $sec = '';
  38.         $ch = '';
  39.  
  40.         // Start
  41.         $first = 0;
  42.         $length = strlen($st);
  43.         $last = $first + $length-1;
  44.         $st = strtoupper($st);
  45.         //$st = str_repeat('-', $first) . strtoupper($st) . str_repeat(' ', 5);
  46.         if (stripos($st, 'W') !== false || stripos($st, 'K') !== false || stripos($st, 'CZ') !== false) {
  47.             $isSlavoGermanic = 1;
  48.         }
  49.  
  50.         $pos = $first;
  51.         $tmp = substr($st, $pos, 2);
  52.         switch ($tmp) {
  53.             case 'GN':
  54.             case 'KN':
  55.             case 'PN':
  56.             case 'WR':
  57.             case 'PS':
  58.                 $pos++;
  59.                 break;
  60.             default:
  61.                 break;
  62.         }
  63.         if (substr($st, $first, 1) == 'X') {
  64.             $pri = 'S';
  65.             $sec = 'S';
  66.             $pos++;
  67.         }
  68.         while ($pos <= $last) {
  69.             $prevpos = $pos;
  70.             $ch = substr($st, $pos, 1);
  71.             switch ($ch) {
  72.                 case 'A':
  73.                 case 'E':
  74.                 case 'I':
  75.                 case 'O':
  76.                 case 'U':
  77.                 case 'Y':
  78.                     if ($pos == $first) {
  79.                         $pri = $pri . 'A';
  80.                         $sec = $sec . 'A';
  81.                         $pos++;
  82.                     } else {
  83.                         $pos++;
  84.                     }
  85.                     break;
  86.                 case 'B':
  87.                     if (substr($st, $pos+1, 1) == 'B') {
  88.                         $pri = $pri . 'P';
  89.                         $sec = $sec . 'P';
  90.                         $pos = $pos + 2;
  91.                     } else {
  92.                         $pri = $pri . 'P';
  93.                         $sec = $sec . 'P';
  94.                         $pos++;
  95.                     }
  96.                     break;
  97.                 case 'C':
  98.                     if ($pos > $first+1 && self::search($st, $pos-2, 1, array('A', 'E', 'I', 'O', 'U', 'Y'), false)
  99.                         && substr($st, $pos-1, 3) == 'ACH' && (self::search($st, $pos+2, 1, array('I', 'E'), false)
  100.                         || self::search($st, $pos-2, 6, array('BACHER', 'MACHER')))
  101.                     ) {
  102.                         $pri = $pri . 'K';
  103.                         $sec = $sec . 'K';
  104.                         $pos = $pos + 2;
  105.                     } elseif ($pos == $first && substr($st, $first, 6) == 'CAESAR') {
  106.                         $pri = $pri . 'S';
  107.                         $sec = $sec . 'S';
  108.                         $pos = $pos + 2;
  109.                     } elseif (substr($st, $pos, 4) == 'CHIA') {
  110.                         $pri = $pri . 'K';
  111.                         $sec = $sec . 'K';
  112.                         $pos = $pos + 2;
  113.                     } elseif (substr($st, $pos, 2) == 'CH') {
  114.                         if ($pos > $first && substr($st, $pos, 4) == 'CHAE') {
  115.                             $pri = $pri . 'K';
  116.                             $sec = $sec . 'X';
  117.                             $pos = $pos + 2;
  118.                         } elseif ($pos == $first && (self::search($st, $pos+1, 5, array('HARAC', 'HARIS'))
  119.                             || self::search($st, $pos+1, 3, array('HOR', 'HYM', 'HIA', 'HEM')))
  120.                             && substr($st, $first, 5) != 'CHORE'
  121.                         ) {
  122.                             $pri = $pri . 'K';
  123.                             $sec = $sec . 'K';
  124.                             $pos = $pos + 2;
  125.                         } elseif (self::search($st, $first, 4, array('VAN ', 'VON ')) || substr($st, $first, 3) == 'SCH'
  126.                             || self::search($st, $pos-2, 6, array('ORCHES', 'ARCHIT', 'ORCHID'))
  127.                             || self::search($st, $pos+2, 1, array('T', 'S')) || ((self::search($st, $pos-1, 1,
  128.                             array('A', 'O', 'U', 'E')) || $pos == $first) && self::search($st, $pos+2, 1,
  129.                             array('L', 'R', 'N', 'M', 'B', 'H', 'F', 'V', 'W', ' ')))
  130.                         ) {
  131.                             $pri = $pri . 'K';
  132.                             $sec = $sec . 'K';
  133.                             $pos = $pos + 2;
  134.                         } else {
  135.                             if ($pos > $first) {
  136.                                 if (substr($st, $first, 2) == 'MC') {
  137.                                     $pri = $pri . 'K';
  138.                                     $sec = $sec . 'K';
  139.                                     $pos = $pos + 2;
  140.                                 } else {
  141.                                     $pri = $pri . 'X';
  142.                                     $sec = $sec . 'K';
  143.                                     $pos = $pos + 2;
  144.                                 }
  145.                             } else {
  146.                                 $pri = $pri . 'X';
  147.                                 $sec = $sec . 'X';
  148.                                 $pos = $pos + 2;
  149.                             }
  150.  
  151.                         }
  152.                     } elseif (substr($st, $pos, 2) == 'CZ' && strpos($st, $pos-2, 4) != 'WICZ') {
  153.                         $pri = $pri . 'S';
  154.                         $sec = $sec . 'X';
  155.                         $pos = $pos + 2;
  156.                     } elseif (substr($st, $pos+1, 3) == 'CIA') {
  157.                         $pri = $pri . 'X';
  158.                         $sec = $sec . 'X';
  159.                         $pos = $pos + 3;
  160.                     } elseif (substr($st, $pos, 2) == 'CC' && ($pos != $first+1 && substr($st, $first, 1) != 'M')) {
  161.                         if (self::search($st, $pos+2, 1, array('I', 'E', 'H')) && substr($st, $pos+2, 2) != 'HU') {
  162.                             if ($pos == $first+1 && substr($st, $first, 1) == 'A' || self::search($st, $pos-1, 5,
  163.                                 array('UCCEE', 'UCCES'))
  164.                             ) {
  165.                                 $pri = $pri . 'KS';
  166.                                 $sec = $sec . 'KS';
  167.                                 $pos = $pos + 3;
  168.                             } else {
  169.                                 $pri = $pri . 'X';
  170.                                 $sec = $sec . 'X';
  171.                                 $pos = $pos + 3;
  172.                             }
  173.                         } else {
  174.                             $pri = $pri . 'K';
  175.                             $sec = $sec . 'K';
  176.                             $pos = $pos + 2;
  177.                         }
  178.                     } elseif (self::search($st, $pos, 2, array('CK', 'CG', 'CQ'))) {
  179.                         $pri = $pri . 'K';
  180.                         $sec = $sec . 'K';
  181.                         $pos = $pos + 2;
  182.                     } elseif (self::search($st, $pos, 2, array('CI', 'CE', 'CY'))) {
  183.                         if (self::search($st, $pos, 3, array('CIO', 'CIE', 'CIA'))) {
  184.                             $pri = $pri . 'S';
  185.                             $sec = $sec . 'X';
  186.                             $pos = $pos + 2;
  187.                         } else {
  188.                             $pri = $pri . 'S';
  189.                             $sec = $sec . 'S';
  190.                             $pos = $pos + 2;
  191.                         }
  192.                     } else {
  193.                         if (self::search($st, $pos+1, 2, array(' C', ' Q', ' G'))) {
  194.                             $pri = $pri . 'K';
  195.                             $sec = $sec . 'K';
  196.                             $pos = $pos + 3;
  197.                         } else {
  198.                             if (self::search($st, $pos+1, 1, array('C', 'K', 'Q')) && self::search($st, $pos+1, 2,
  199.                                 array('CE', 'CI'), false)
  200.                             ) {
  201.                                 $pri = $pri . 'K';
  202.                                 $sec = $sec . 'K';
  203.                                 $pos = $pos + 2;
  204.                             } else {
  205.                                 $pri = $pri . 'K';
  206.                                 $sec = $sec . 'K';
  207.                                 $pos = $pos++;
  208.                             }
  209.                         }
  210.                     }
  211.                     break;
  212.                 case 'D':
  213.                     if (substr($st, $pos, 2) == 'DG') {
  214.                         $tmp = substr($st, $pos+2, 1);
  215.                         if ($tmp == 'I' || $tmp == 'E' || $tmp == 'Y') {
  216.                             $pri = $pri . 'J';
  217.                             $sec = $sec . 'J';
  218.                             $pos = $pos + 3;
  219.                         } else {
  220.                             $pri = $pri . 'TK';
  221.                             $sec = $sec . 'TK';
  222.                             $pos = $pos + 2;
  223.                         }
  224.                     } elseif (self::search($st, $pos, 2, array('DT', 'DD'))) {
  225.                         $pri = $pri . 'T';
  226.                         $sec = $sec . 'T';
  227.                         $pos = $pos + 2;
  228.                     } else {
  229.                         $pri = $pri . 'T';
  230.                         $sec = $sec . 'T';
  231.                         $pos++;
  232.                     }
  233.                     break;
  234.                 case 'F':
  235.                     if (substr($st, $pos+1, 1) == 'V') {
  236.                         $pri = $pri . 'F';
  237.                         $sec = $sec . 'F';
  238.                         $pos = $pos + 2;
  239.                     } else {
  240.                         $pri = $pri . 'F';
  241.                         $sec = $sec . 'F';
  242.                         $pos++;
  243.                     }
  244.                     break;
  245.                 case 'G':
  246.                     if (substr($st, $pos+1, 1) == 'H') {
  247.                         if (($pos > $first && self::search($st, $pos-1, 1, array('A', 'E', 'I', 'O', 'U', 'Y'), false))
  248.                             || ($pos == $first && substr($st, $pos+2, 1) != 'I')
  249.                         ) {
  250.                              $pri = $pri . 'K';
  251.                              $sec = $sec . 'K';
  252.                              $pos = $pos + 2;
  253.                          } elseif ($pos == $first && substr($st, $pos+2, 1) == 'I') {
  254.                              $pri = $pri . 'J';
  255.                              $sec = $sec . 'J';
  256.                              $pos = $pos + 2;
  257.                          } elseif (($pos > $first+1 && self::search($st, $pos-2, 1, array('B', 'H', 'D')))
  258.                              || ($pos > $first+2 && self::search($st, $pos-3, 1, array('B', 'H', 'D')))
  259.                              || ($pos > $first+3 && self::search($st, $pos-4, 1, array('B', 'H')))
  260.                          ) {
  261.                              $pos = $pos + 2;
  262.                          } else {
  263.                              if ($pos > $first+2 && substr($st, $pos-1, 1) == 'U' && self::search($st, $pos-3, 1,
  264.                                  array('C', 'G', 'L', 'R', 'T'))
  265.                              ) {
  266.                                  $pri = $pri . 'F';
  267.                                  $sec = $sec . 'F';
  268.                                  $pos = $pos + 2;
  269.                              } elseif ($pos > $first && substr($st, $pos-1, 1) != 'I') {
  270.                                  $pri = $pri . 'F';
  271.                                  $sec = $sec . 'F';
  272.                                  $pos = $pos + 2;
  273.                              } else {
  274.                                  $pos++;
  275.                              }
  276.                          }
  277.                     } elseif (substr($st, $pos+1, 1) == 'N') {
  278.                         if ($pos == $first+1 && self::search($st, $first, 1, array('A', 'E', 'I', 'O', 'U', 'Y'))
  279.                             && $isSlavoGermanic == 0
  280.                         ) {
  281.                             $pri = $pri . 'KN';
  282.                             $sec = $sec . 'N';
  283.                             $pos = $pos + 2;
  284.                         } else {
  285.                             if (substr($st, $pos+2, 2) != 'EY' && substr($st, $pos+1, 1) != 'Y'
  286.                                 && $isSlavoGermanic != 1
  287.                             ) {
  288.                                 $pri = $pri . 'N';
  289.                                 $sec = $sec . 'KN';
  290.                                 $pos = $pos + 2;
  291.                             } else {
  292.                                 $pri = $pri . 'KN';
  293.                                 $sec = $sec . 'KN';
  294.                                 $pos = $pos + 2;
  295.                             }
  296.                         }
  297.                     } elseif (substr($st, $pos+1, 2) == 'LI' && $isSlavoGermanic == 0) {
  298.                         $pri = $pri . 'KL';
  299.                         $sec = $sec . 'L';
  300.                         $pos = $pos + 2;
  301.                     } elseif ($pos == $first && (substr($st, $pos+1, 1) == 'Y' || self::search($st, $pos+1, 2,
  302.                         array('ES', 'EP', 'EB', 'EL', 'EY', 'IB', 'IL', 'IN', 'IE', 'EI', 'ER')))
  303.                     ) {
  304.                         $pri = $pri . 'K';
  305.                         $sec = $sec . 'J';
  306.                         $pos = $pos + 2;
  307.                     } elseif (substr($st, $pos+1, 2) == 'ER' || substr($st, $pos+1, 1) == 'Y'
  308.                         && self::search($st, $first, 6, array('DANGER', 'RANGER', 'MANGER'), false)
  309.                         && self::search($st, $pos-1, 1, array('E', 'I'), false)
  310.                         && self::search($st, $pos-1, 3, array('RGY', 'OGY'), false)
  311.                     ) {
  312.                         $pri = $pri . 'K';
  313.                         $sec = $sec . 'J';
  314.                         $pos = $pos + 2;
  315.                     } elseif (self::search($st, $pos+1, 1, array('E', 'I', 'Y')) || self::search($st, $pos-1, 4,
  316.                         array('AGGI', 'OGGI'))
  317.                     ) {
  318.                         if (self::search($st, $first, 4, array('VON ', 'VAN ')) || substr($st, $first, 3) == 'SCH'
  319.                             || substr($st, $pos+1, 2) == 'ET'
  320.                         ) {
  321.                             $pri = $pri . 'K';
  322.                             $sec = $sec . 'K';
  323.                             $pos = $pos + 2;
  324.                         } else {
  325.                             if (substr($st, $pos+1, 4) == 'IER ') {
  326.                                 $pri = $pri . 'J';
  327.                                 $sec = $sec . 'J';
  328.                                 $pos = $pos + 2;
  329.                             } else {
  330.                                 $pri = $pri . 'J';
  331.                                 $sec = $sec . 'K';
  332.                                 $pos = $pos + 2;
  333.                             }
  334.                         }
  335.                     } elseif (substr($st, $pos+1, 1) == 'G') {
  336.                         $pri = $pri . 'K';
  337.                         $sec = $sec . 'K';
  338.                         $pos = $pos + 2;
  339.                     } else {
  340.                         $pri = $pri . 'K';
  341.                         $sec = $sec . 'K';
  342.                         $pos = $pos++;
  343.                     }
  344.                     break;
  345.                 case 'H':
  346.                     if (($pos == $first || self::search($st, $pos-1, 1, array('A', 'E', 'I', 'O', 'U', 'Y')))
  347.                         && self::search($st, $pos+1, 1, array('A', 'E', 'I', 'O', 'U', 'Y'))
  348.                     ) {
  349.                         $pri = $pri . 'H';
  350.                         $sec = $sec . 'H';
  351.                         $pos = $pos + 2;
  352.                     } else {
  353.                         $pos++;
  354.                     }
  355.                     break;
  356.                 case 'J':
  357.                     if (substr($st, $pos, 4) == 'JOSE' || substr($st, $first, 4) == 'SAN ') {
  358.                         if (($pos == $first && substr($st, $pos+4, 1) == ' ') || substr($st, $first, 4) == 'SAN ') {
  359.                             $pri = $pri . 'H';
  360.                             $sec = $sec . 'H';
  361.                         } else {
  362.                             $pri = $pri . 'J';
  363.                             $sec = $sec . 'H';
  364.                         }
  365.                     } elseif ($pos == $first && substr($st, $pos, 4) != 'JOSE') {
  366.                         $pri = $pri . 'J';
  367.                         $sec = $sec . 'A';
  368.                     } else {
  369.                         if (self::search($st, $pos-1, 1, array('A', 'E', 'I', 'O', 'U', 'Y')) && $isSlavoGermanic == 0
  370.                             && self::search($st, $pos+1, 1, array('A', 'O'))
  371.                         ) {
  372.                             $pri = $pri . 'J';
  373.                             $sec = $sec . 'H';
  374.                         } else {
  375.                             if ($pos == $last) {
  376.                                 $pri = $pri . 'J';
  377.                             } else {
  378.                                 if (self::search($st, $pos+1, 1, array('L', 'T', 'K', 'S', 'N', 'M', 'B', 'Z'), false)
  379.                                     && self::search($st, $pos-1, 1, array('S', 'K', 'L'), false)
  380.                                 ) {
  381.                                     $pri = $pri . 'J';
  382.                                     $sec = $sec . 'J';
  383.                                 }
  384.                             }
  385.                         }
  386.                     }
  387.                     if (substr($st, $pos+1, 1) == 'J') {
  388.                         $pos = $pos + 2;
  389.                     } else {
  390.                         $pos++;
  391.                     }
  392.                     break;
  393.                 case 'K':
  394.                     if (substr($st, $pos+1, 1) == 'K') {
  395.                         $pri = $pri . 'K';
  396.                         $sec = $sec . 'K';
  397.                         $pos = $pos + 2;
  398.                     } else {
  399.                         $pri = $pri . 'K';
  400.                         $sec = $sec . 'K';
  401.                         $pos++;
  402.                     }
  403.                     break;
  404.                 case 'L':
  405.                     if (substr($st, $pos+1, 1) == 'L') {
  406.                         if (($pos == $last-2 && self::search($st, $pos-1, 4, array('ILLO', 'ILLA', 'ALLE')))
  407.                             || ((self::search($st, $last-1, 2, array('AS', 'OS'))
  408.                             || self::search($st, $last, null, array('A', 'O'))) && substr($st, $pos-1, 4 == 'ALLE'))
  409.                         ) {
  410.                             $pri = $pri . 'L';
  411.                             $pos = $pos + 2;
  412.                         } else {
  413.                             $pri = $pri . 'L';
  414.                             $sec = $sec . 'L';
  415.                             $pos = $pos + 2;
  416.                         }
  417.                     } else {
  418.                         $pri = $pri . 'L';
  419.                         $sec = $sec . 'L';
  420.                         $pos++;
  421.                     }
  422.                     break;
  423.                 case 'M':
  424.                     if (substr($st, $pos-1, 3) == 'UMB' && ($pos+1 == $last || substr($st, $pos+2, 2) == 'ER')
  425.                         || substr($st, $pos+1, 1) == 'M'
  426.                     ) {
  427.                         $pri = $pri . 'M';
  428.                         $sec = $sec . 'M';
  429.                         $pos = $pos + 2;
  430.                     } else {
  431.                         $pri = $pri . 'M';
  432.                         $sec = $sec . 'M';
  433.                         $pos++;
  434.                     }
  435.                     break;
  436.                 case 'N':
  437.                     if (substr($st, $pos+1, 1) == 'N') {
  438.                         $pri = $pri . 'N';
  439.                         $sec = $sec . 'N';
  440.                         $pos = $pos + 2;
  441.                     } else {
  442.                         $pri = $pri . 'N';
  443.                         $sec = $sec . 'N';
  444.                         $pos++;
  445.                     }
  446.                     break;
  447.                 case 'P':
  448.                     if (substr($st, $pos+1, 1) == 'H') {
  449.                         $pri = $pri . 'F';
  450.                         $sec = $sec . 'F';
  451.                         $pos = $pos + 2;
  452.                     } elseif (self::search($st, $pos+1, 1, array('P', 'B'))) {
  453.                         $pri = $pri . 'P';
  454.                         $sec = $sec . 'P';
  455.                         $pos = $pos + 2;
  456.                     } else {
  457.                         $pri = $pri . 'P';
  458.                         $sec = $sec . 'P';
  459.                         $pos++;
  460.                     }
  461.                     break;
  462.                 case 'Q':
  463.                     if (substr($st, $pos+1, 1) == 'Q') {
  464.                         $pri = $pri . 'K';
  465.                         $sec = $sec . 'K';
  466.                         $pos = $pos +2;
  467.                     } else {
  468.                         $pri = $pri . 'K';
  469.                         $sec = $sec . 'K';
  470.                         $pos++;
  471.                     }
  472.                     break;
  473.                 case 'R':
  474.                     if ($pos == $last && $isSlavoGermanic != 1 && substr($st, $pos-2, 2) == 'IE'
  475.                         && self::search($st, $pos-4, 2, array('ME', 'MA'), false)
  476.                     ) {
  477.                         $sec = $sec . 'R';
  478.                     } else {
  479.                         $pri = $pri . 'R';
  480.                         $sec = $sec . 'R';
  481.                     }
  482.                     if (substr($st, $pos+1, 1) == 'R') {
  483.                         $pos = $pos + 2;
  484.                     } else {
  485.                         $pos++;
  486.                     }
  487.                     break;
  488.                 case 'S':
  489.                     if (self::search($st, $pos-1, 3, array('ISL', 'YSL'))) {
  490.                         $pos++;
  491.                     } elseif ($pos == $first && substr($st, $first, 5) == 'SUGAR') {
  492.                         $pri = $pri . 'X';
  493.                         $sec = $sec . 'S';
  494.                         $pos = $pos++;
  495.                     } elseif (substr($st, $pos, 2) == 'SH') {
  496.                         if (self::search($st, $pos+1, 4, array('HEIM', 'HOEK', 'HOLM', 'HOLZ'))) {
  497.                             $pri = $pri . 'S';
  498.                             $sec = $sec . 'S';
  499.                             $pos = $pos + 2;
  500.                         } else {
  501.                             $pri = $pri . 'X';
  502.                             $sec = $sec . 'X';
  503.                             $pos = $pos + 2;
  504.                         }
  505.                     } elseif (self::search($st, $pos, 3, array('SIO', 'SIA')) || substr($st, $pos, 4) == 'SIAN') {
  506.                         if ($isSlavoGermanic != 1) {
  507.                             $pri = $pri . 'S';
  508.                             $sec = $sec . 'X';
  509.                             $pos = $pos + 3;
  510.                         } else {
  511.                             $pri = $pri . 'S';
  512.                             $sec = $sec . 'S';
  513.                             $pos = $pos + 3;
  514.                         }
  515.                     } elseif (($pos == $first && self::search($st, $pos+1, 1, array('M', 'N', 'L', 'W')))
  516.                         || substr($st, $pos+1, 1) == 'Z'
  517.                     ) {
  518.                         $pri = $pri . 'S';
  519.                         $sec = $sec . 'X';
  520.                         if (substr($st, $pos+1, 1) == 'Z') {
  521.                             $pos = $pos + 2;
  522.                         } else {
  523.                             $pos++;
  524.                         }
  525.                     } elseif (substr($st, $pos, 2) == 'SC') {
  526.                         if (substr($st, $pos+2, 1) == 'H') {
  527.                             if (self::search($st, $pos+3, 2, array('OO', 'ER', 'EN', 'UY', 'ED', 'EM'))) {
  528.                                 if (self::search($st, $pos+3, 2, array('ER', 'EN'))) {
  529.                                     $pri = $pri . 'X';
  530.                                     $sec = $sec . 'SK';
  531.                                     $pos = $pos + 3;
  532.                                 } else {
  533.                                     $pri = $pri . 'SK';
  534.                                     $sec = $sec . 'SK';
  535.                                     $pos = $pos + 3;
  536.                                 }
  537.                             } else {
  538.                                 if ($pos == $first && self::search($st, $first+3, 1, array('A', 'E', 'I', 'O', U, Y),
  539.                                     false && substr($st, $first+3, 1) != 'W')
  540.                                 ) {
  541.                                     $pri = $pri . 'X';
  542.                                     $sec = $sec . 'S';
  543.                                     $pos = $pos + 3;
  544.                                 } else {
  545.                                     $pri = $pri . 'X';
  546.                                     $sec = $sec . 'X';
  547.                                     $pos = $pos + 3;
  548.                                 }
  549.                             }
  550.                         } elseif (self::search($st, $pos+2, 1, array('I', 'E', 'Y'))) {
  551.                             $pri = $pri . 'S';
  552.                             $sec = $sec . 'S';
  553.                             $pos = $pos + 3;
  554.                         } else {
  555.                             $pri = $pri . 'SK';
  556.                             $sec = $sec . 'SK';
  557.                             $pos = $pos + 3;
  558.                         }
  559.                     } elseif ($pos == $last && self::search($st, $pos-2, 2, array('AI', 'OI'))) {
  560.                         $sec = $sec . 'S';
  561.                         $pos++;
  562.                     } else {
  563.                         $pri = $pri . 'S';
  564.                         $sec = $sec . 'S';
  565.                         if (self::search($st, $pos+1, 1, array('S', 'Z'))) {
  566.                             $pos = $pos + 2;
  567.                         } else {
  568.                             $pos++;
  569.                         }
  570.                     }
  571.                     break;
  572.                 case 'T':
  573.                     if (substr($st, $pos, 4) == 'TION') {
  574.                         $pri = $pri . 'X';
  575.                         $sec = $sec . 'X';
  576.                         $pos = $pos + 3;
  577.                     } elseif (self::search($st, $pos, 3, array('TIA', 'TCH'))) {
  578.                         $pri = $pri . 'X';
  579.                         $sec = $sec . 'X';
  580.                         $pos = $pos + 3;
  581.                     } elseif (substr($st, $pos, 2) == 'TH' || substr($st, $pos, 3) == 'TTH') {
  582.                         if (self::search($st, $pos+2, 2, array('OM', 'AM'))
  583.                             || self::search($st, $first, 4, array('VON ', 'VAN ')) || substr($st, $first, 3) == 'SCH'
  584.                         ) {
  585.                             $pri = $pri . 'T';
  586.                             $sec = $sec . 'T';
  587.                             $pos = $pos + 2;
  588.                         } else {
  589.                             $pri = $pri . 'O';
  590.                             $sec = $sec . 'T';
  591.                             $pos = $pos + 2;
  592.                         }
  593.                     } elseif (self::search($st, $pos+1, 1, array('T', 'D'))) {
  594.                         $pri = $pri . 'T';
  595.                         $sec = $sec . 'T';
  596.                         $pos = $pos + 2;
  597.                     } else {
  598.                         $pri = $pri . 'T';
  599.                         $sec = $sec . 'T';
  600.                         $pos = $pos++;
  601.                     }
  602.                     break;
  603.                 case 'V':
  604.                     if (substr($st, $pos+1, 1) == 'V') {
  605.                         $pri = $pri . 'F';
  606.                         $sec = $sec . 'F';
  607.                         $pos = $pos + 2;
  608.                     } else {
  609.                         $pri = $pri . 'F';
  610.                         $sec = $sec . 'F';
  611.                         $pos = $pos++;
  612.                     }
  613.                     break;
  614.                 case 'W':
  615.                     $tmp = substr($st, $pos+1, 1);
  616.                     $tmp2 = substr($st, $pos-1, 1);
  617.                     $tmp3 = substr($st, $pos-1, 5);
  618.                     if (substr($st, $pos, 2) == 'WR') {
  619.                         $pri = $pri . 'R';
  620.                         $sec = $pri . 'R';
  621.                         $pos = $pos + 2;
  622.                     } elseif ($pos == $first && ($tmp == 'A' || $tmp == 'E' || $tmp == 'I' || $tmp == 'O' || $tmp == 'U' ||
  623.                         $tmp == 'Y' || substr($st, $pos, 2) == 'WH')) {
  624.                         $tmp = substr($st, $pos+1, 1);
  625.                         if ($tmp == 'A' || $tmp == 'E' || $tmp == 'I' || $tmp == 'O' || $tmp == 'U' || $tmp == 'Y') {
  626.                             $pri = $pri . 'A';
  627.                             $sec = $sec . 'F';
  628.                             $pos++;
  629.                         } else {
  630.                             $pri = $pri . 'A';
  631.                             $sec = $sec . 'A';
  632.                             $pos++;
  633.                         }
  634.                     } elseif (($pos == $last && ($tmp2 == 'A' || $tmp2 == 'E' || $tmp2 == 'I' || $tmp2 == 'O' ||
  635.                         $tmp2 == 'U' || $tmp2 == 'Y')) || $tmp3 == 'EWSKI' || $tmp3 == 'EWSKY' || $tmp3 == 'OWSKI' ||
  636.                         $tmp3 == 'OWSKY' || substr($st, $first, 3) == 'SCH') {
  637.                         $sec = $sec . 'F';
  638.                         $pos++;
  639.                     } elseif (substr($st, $pos, 4) == 'WICZ' || substr($st, $pos, 4) == 'WITZ') {
  640.                         $pri = $pri . 'TS';
  641.                         $sec = $sec . 'FX';
  642.                         $pos = $pos + 4;
  643.                     } else {
  644.                         $pos++;
  645.                     }
  646.                     break;
  647.                 case 'X':
  648.                     if (($pos != $last && (substr($st, $pos-3, 3) != 'IAU' || substr($st, $pos-3, 3) != 'EAU'))
  649.                         || (substr($st, $pos-2, 2) != 'AU' || substr($st, $pos-2, 2) != 'OU')
  650.                     ) {
  651.                         $pri = $pri . 'KS';
  652.                         $sec = $sec . 'KS';
  653.                     }
  654.                     if (substr($st, $pos+1, 1) == 'C' || substr($st, $pos+1, 1) == 'X') {
  655.                         $pos = $pos + 2;
  656.                     } else {
  657.                         $pos++;
  658.                     }
  659.                     break;
  660.                 case 'Z':
  661.                     if (substr($st, $pos+1, 1) == 'H') {
  662.                         $pri = $pri . 'J';
  663.                         $sec = $sec . 'J';
  664.                         $pos++;
  665.                     } elseif ((substr($st, $pos+1, 3) == 'ZO' || substr($st, $pos+1, 3) == 'ZI' || substr($st, $pos+1, 3) == 'ZA')
  666.                         || ($isSlavoGermanic == 1 && $pos > $first && substr($st, $pos-1, 1) != 'T')
  667.                     ) {
  668.                         $pri = $pri . 'S';
  669.                         $sec = $sec . 'TS';
  670.                     } else {
  671.                         $pri = $pri . 'S';
  672.                         $sec = $sec . 'S';
  673.                     }
  674.                     if (substr($st, $pos+1, 1) == 'Z') {
  675.                         $pos = $pos+2;
  676.                     } else {
  677.                         $pos++;
  678.                     }
  679.                     break;
  680.                 default:
  681.                     $pos++;
  682.                     break;
  683.             }
  684.             if ($pos == $prevpos) {
  685.                 $pos++;
  686.             }
  687.         }
  688.         if ($pri != $sec) {
  689.             return $pri . ';' . $sec;
  690.         }
  691.         return $pri;
  692.     }
  693. }