Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
99.67% |
301 / 302 |
|
87.50% |
7 / 8 |
CRAP | |
0.00% |
0 / 1 |
CrhExceptions | |
99.67% |
301 / 302 |
|
87.50% |
7 / 8 |
17 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
initLcUc | |
90.00% |
9 / 10 |
|
0.00% |
0 / 1 |
4.02 | |||
myLc | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
myUc | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
myUcWord | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
addMappings | |
100.00% |
16 / 16 |
|
100.00% |
1 / 1 |
7 | |||
loadExceptions | |
100.00% |
15 / 15 |
|
100.00% |
1 / 1 |
1 | |||
loadRegs | |
100.00% |
257 / 257 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | namespace MediaWiki\Languages\Data; |
3 | |
4 | use CrhConverter as Crh; |
5 | |
6 | /** |
7 | * Exceptions Tables for Crimean Tatar (crh / Qırımtatarca) |
8 | * |
9 | * Adapted from https://crh.wikipedia.org/wiki/Qullan%C4%B1c%C4%B1:Don_Alessandro/Translit |
10 | * |
11 | * @ingroup Language |
12 | */ |
13 | class CrhExceptions { |
14 | |
15 | private const WB = '\b'; # default word boundary; may be updated in the future |
16 | |
17 | public function __construct() { |
18 | $this->loadRegs(); |
19 | } |
20 | |
21 | public $Cyrl2LatnExceptions = []; |
22 | public $Latn2CyrlExceptions = []; |
23 | |
24 | public $Cyrl2LatnPatterns = []; |
25 | public $Latn2CyrlPatterns = []; |
26 | |
27 | private $lc2uc; |
28 | private $uc2lc; |
29 | |
30 | private function initLcUc( $lcChars, $ucChars, $reinit = false ) { |
31 | # bail if we've already done this, unless we are re-initializing |
32 | if ( !$reinit && $this->lc2uc && $this->uc2lc ) { |
33 | return; |
34 | } |
35 | |
36 | # split up the lc and uc lists in a unicode-friendly way |
37 | $myLc = []; |
38 | preg_match_all( '/./u', $lcChars, $myLc ); |
39 | $myLc = $myLc[0]; |
40 | |
41 | $myUc = []; |
42 | preg_match_all( '/./u', $ucChars, $myUc ); |
43 | $myUc = $myUc[0]; |
44 | |
45 | # map lc to uc and vice versa |
46 | $this->lc2uc = array_combine( array_values( $myLc ), array_values( $myUc ) ); |
47 | $this->uc2lc = array_combine( array_values( $myUc ), array_values( $myLc ) ); |
48 | } |
49 | |
50 | private function myLc( $string ) { |
51 | return strtr( $string, $this->uc2lc ); |
52 | } |
53 | |
54 | private function myUc( $string ) { |
55 | return strtr( $string, $this->lc2uc ); |
56 | } |
57 | |
58 | private function myUcWord( $string ) { |
59 | return $this->myUc( mb_substr( $string, 0, 1 ) ) . $this->myLc( mb_substr( $string, 1 ) ); |
60 | } |
61 | |
62 | private function addMappings( $mapArray, &$A2B, &$B2A, $exactCase = false, |
63 | $prePat = '', $postPat = '' ) { |
64 | foreach ( $mapArray as $WordA => $WordB ) { |
65 | if ( !$exactCase ) { |
66 | $ucA = $this->myUc( $WordA ); |
67 | $ucWordA = $this->myUcWord( $WordA ); |
68 | $ucB = $this->myUc( $WordB ); |
69 | $ucWordB = $this->myUcWord( $WordB ); |
70 | } |
71 | |
72 | # if there are regexes, only map toward backregs |
73 | if ( !preg_match( '/\$[1-9]/', $WordA ) ) { |
74 | $A2B[ $prePat . $WordA . $postPat ] = $WordB; |
75 | if ( !$exactCase ) { |
76 | // @phan-suppress-next-line PhanPossiblyUndeclaredVariable uc vars are set when used |
77 | $A2B[ $prePat . $ucWordA . $postPat ] = $ucWordB; |
78 | // @phan-suppress-next-line PhanPossiblyUndeclaredVariable uc vars are set when used |
79 | $A2B[ $prePat . $ucA . $postPat ] = $ucB; |
80 | } |
81 | } |
82 | |
83 | if ( !preg_match( '/\$[1-9]/', $WordB ) ) { |
84 | $B2A[ $prePat . $WordB . $postPat ] = $WordA; |
85 | if ( !$exactCase ) { |
86 | // @phan-suppress-next-line PhanPossiblyUndeclaredVariable uc vars are set when used |
87 | $B2A[ $prePat . $ucWordB . $postPat ] = $ucWordA; |
88 | // @phan-suppress-next-line PhanPossiblyUndeclaredVariable uc vars are set when used |
89 | $B2A[ $prePat . $ucB . $postPat ] = $ucA; |
90 | } |
91 | } |
92 | } |
93 | } |
94 | |
95 | public function loadExceptions( $lcChars, $ucChars ) { |
96 | # init lc and uc, as needed |
97 | $this->initLcUc( $lcChars, $ucChars ); |
98 | |
99 | # no regex prefix/suffix needed |
100 | $this->addMappings( $this->ManyToOneC2LMappings, |
101 | // reverse exception mapping order to handle many-to-one C2L mappings |
102 | $this->Latn2CyrlExceptions, $this->Cyrl2LatnExceptions ); |
103 | $this->addMappings( $this->multiCaseMappings, |
104 | $this->Cyrl2LatnExceptions, $this->Latn2CyrlExceptions ); |
105 | $this->addMappings( $this->exactCaseMappings, |
106 | $this->Cyrl2LatnExceptions, $this->Latn2CyrlExceptions, true ); |
107 | |
108 | # load C2L and L2C bidirectional affix mappings |
109 | $this->addMappings( $this->prefixMapping, |
110 | $this->Cyrl2LatnPatterns, $this->Latn2CyrlPatterns, false, '/' . self::WB, '/u' ); |
111 | $this->addMappings( $this->suffixMapping, |
112 | $this->Cyrl2LatnPatterns, $this->Latn2CyrlPatterns, false, '/', self::WB . '/u' ); |
113 | |
114 | # tack on one-way mappings to the ends of the prefix and suffix patterns |
115 | $this->Cyrl2LatnPatterns += $this->Cyrl2LatnRegexes; |
116 | $this->Latn2CyrlPatterns += $this->Latn2CyrlRegexes; |
117 | |
118 | return [ $this->Cyrl2LatnExceptions, $this->Latn2CyrlExceptions, $this->Cyrl2LatnPatterns, |
119 | $this->Latn2CyrlPatterns, $this->CyrlCleanUpRegexes ]; |
120 | } |
121 | |
122 | /** |
123 | * @var string[] map Latin to Cyrillic and back, simple string match only (no regex) |
124 | * variants: all lowercase, all uppercase, first letter capitalized |
125 | */ |
126 | private $ManyToOneC2LMappings = [ |
127 | # Carefully ordered many-to-one mapping. |
128 | # These are ordered so that the C2L is correct (the later Latin one). |
129 | # See also the L2C mappings below |
130 | 'fevqülade' => 'февкъульаде', 'fevqulade' => 'февкъульаде', |
131 | 'beyude' => 'бейуде', 'beyüde' => 'бейуде', |
132 | 'curat' => 'джурьат', 'cürat' => 'джурьат', |
133 | 'mesul' => 'месуль', 'mesül' => 'месуль', |
134 | ]; |
135 | |
136 | /** |
137 | * @var string[] map Cyrillic to Latin and back, simple string match only (no regex) |
138 | * variants: all lowercase, all uppercase, first letter capitalized |
139 | */ |
140 | private $multiCaseMappings = [ |
141 | |
142 | #### Cyrillic to Latin |
143 | 'аджыумер' => 'acıümer', 'аджыусеин' => 'acıüsein', 'алейкум' => 'aleyküm', |
144 | 'бозтюс' => 'boztüs', 'боливия' => 'boliviya', 'большевик' => 'bolşevik', 'борис' => 'boris', |
145 | 'борнен' => 'bornen', 'бублик' => 'bublik', 'буддизм' => 'buddizm', 'буддист' => 'buddist', |
146 | 'буженина' => 'bujenina', 'бузкесен' => 'buzkesen', 'букинист' => 'bukinist', |
147 | 'буксир' => 'buksir', 'бульбул' => 'bülbül', 'бульвар' => 'bulvar', 'бульдог' => 'buldog', |
148 | 'бульдозер' => 'buldozer', 'бульон' => 'bulyon', 'бумеранг' => 'bumerang', |
149 | 'бунен' => 'bunen', 'буннен' => 'bunnen', 'бус-бутюн' => 'büs-bütün', |
150 | 'бутерброд' => 'buterbrod', 'бутилен' => 'butilen', 'бутилир' => 'butilir', |
151 | 'буфер' => 'bufer', 'буфет' => 'bufet', 'гобелен' => 'gobelen', 'гомео' => 'gomeo', |
152 | 'горизонт' => 'gorizont', 'госпитал' => 'gospital', 'готтентот' => 'gottentot', |
153 | 'гофрир' => 'gofrir', 'губерн' => 'gubern', 'гуверн' => 'guvern', 'гугенот' => 'gugenot', |
154 | 'гуливер' => 'guliver', 'гуна' => 'güna', 'гунях' => 'günâh', 'гургуль' => 'gürgül', |
155 | 'гуя' => 'güya', 'дёрткуль' => 'dörtkül', 'джуньджу' => 'cüncü', 'ёлнен' => 'yolnen', |
156 | 'зумбуль' => 'zümbül', 'ильи' => 'ilyi', 'ишунь' => 'işün', 'ковер' => 'kover', 'код' => 'kod', |
157 | 'койлю' => 'köylü', 'кокагъач' => 'kökağaç', 'кокбаштанкъара' => 'kökbaştanqara', |
158 | 'кокгогерджин' => 'kökgögercin', 'кокдогъан' => 'kökdoğan', 'коккозю' => 'kökközü', |
159 | 'коккъузгъун' => 'kökquzğun', 'коклюш' => 'koklüş', 'кокташ' => 'köktaş', |
160 | 'коктогъан' => 'köktoğan', 'коктотай' => 'köktotay', 'коллег' => 'kolleg', |
161 | 'коллект' => 'kollekt', 'коллекц' => 'kollekts', 'колье' => 'kolye', 'кольраби' => 'kolrabi', |
162 | 'кольцов' => 'koltsov', 'комби' => 'kombi', 'комеди' => 'komedi', 'коменда' => 'komenda', |
163 | 'комета' => 'kometa', 'комив' => 'komiv', 'комис' => 'komis', 'комит' => 'komit', |
164 | 'комм' => 'komm', 'коммент' => 'komment', 'коммерс' => 'kommers', 'коммерц' => 'kommerts', |
165 | 'комп' => 'komp', 'конве' => 'konve', 'конгени' => 'kongeni', 'конденс' => 'kondens', |
166 | 'кондил' => 'kondil', 'кондитер' => 'konditer', 'кондиц' => 'kondits', 'коник' => 'konik', |
167 | 'конкис' => 'konkis', 'консерв' => 'konserv', 'конси' => 'konsi', 'контейнер' => 'konteyner', |
168 | 'конти' => 'konti', 'конфе' => 'konfe', 'конфи' => 'konfi', 'конце' => 'kontse', |
169 | 'конъю' => 'konyu', 'коньки' => 'konki', 'коньяк' => 'konyak', 'копирле' => 'kopirle', |
170 | 'копия' => 'kopiya', 'корде' => 'korde', 'кореиз' => 'koreiz', 'коренн' => 'korenn', |
171 | 'корея' => 'koreya', 'кориа' => 'koria', 'коридор' => 'koridor', 'корне' => 'korne', |
172 | 'корнеев' => 'korneyev', 'корни' => 'korni', 'корре' => 'korre', 'косме' => 'kosme', |
173 | 'космик' => 'kosmik', 'костюм' => 'kostüm', 'котельн' => 'koteln', 'котир' => 'kotir', |
174 | 'котлет' => 'kotlet', 'кочерг' => 'koçerg', 'коше' => 'köşe', 'куби' => 'kubi', |
175 | 'кудрин' => 'kudrin', 'кузнец' => 'kuznets', 'кулинар' => 'kulinar', 'кулич' => 'kuliç', |
176 | 'кульмин' => 'kulmin', 'культаш' => 'kültaş', 'культе' => 'külte', 'культ' => 'kult', |
177 | 'куркулет' => 'kürkület', 'курсив' => 'kursiv', 'кушет' => 'kuşet', 'кушку' => 'küşkü', |
178 | 'куюк' => 'küyük', 'къолязма' => 'qolyazma', 'къуртумер' => 'qurtümer', |
179 | 'къуртусеин' => 'qurtüsein', 'медьюн' => 'medyun', 'месули' => 'mesüli', |
180 | 'мефкуре' => 'mefküre', 'могедек' => 'mögedek', 'мумиё' => 'mumiyo', 'мумиф' => 'mumif', |
181 | 'муче' => 'müçe', 'муюз' => 'müyüz', 'нумюне' => 'nümüne', 'обел' => 'obel', 'обер' => 'ober', |
182 | 'обли' => 'obli', 'обсе' => 'obse', 'обт' => 'obt', 'огне' => 'ogne', 'одеколон' => 'odekolon', |
183 | 'одеса' => 'odesa', 'одесса' => 'odessa', 'озерки' => 'ozerki', 'озерн' => 'ozern', |
184 | 'озёрн' => 'ozörn', 'озюя' => 'özüya', 'океан' => 'okean', 'окси' => 'oksi', |
185 | 'октет' => 'oktet', 'олеа' => 'olea', 'олеи' => 'olei', 'оленев' => 'olenev', 'олив' => 'oliv', |
186 | 'олиг' => 'olig', 'олимп' => 'olimp', 'олиф' => 'olif', 'ольчер' => 'ölçer', 'омле' => 'omle', |
187 | 'онен' => 'onen', 'оннен' => 'onnen', 'опера' => 'opera', 'опере' => 'opere', |
188 | 'оптим' => 'optim', 'опци' => 'optsi', 'орби' => 'orbi', 'орден' => 'orden', |
189 | 'ордер' => 'order', 'ордин' => 'ordin', 'ореа' => 'orea', 'орех' => 'oreh', |
190 | 'ориент' => 'oriyent', 'оркестр' => 'orkestr', 'орлин' => 'orlin', 'орни' => 'orni', |
191 | 'орхи' => 'orhi', 'осци' => 'ostsi', 'офис' => 'ofis', 'офиц' => 'ofits', 'офсет' => 'ofset', |
192 | 'очерк' => 'oçerk', 'оюннен' => 'oyunnen', 'побед' => 'pobed', 'полево' => 'polevo', |
193 | 'поли' => 'poli', 'полюшко' => 'polüşko', 'помидор' => 'pomidor', 'пониз' => 'poniz', |
194 | 'порфир' => 'porfir', 'потелов' => 'potelov', 'потюк' => 'pötük', 'почетн' => 'poçetn', |
195 | 'почётн' => 'poçötn', 'пукле' => 'pükle', 'пуркю' => 'pürkü', 'пурумют' => 'purümüt', |
196 | 'пускул' => 'püskül', 'пускур' => 'püskür', 'пусюр' => 'püsür', 'пуфле' => 'püfle', |
197 | 'сейитумер' => 'seyitümer', 'сейитусеин' => 'seyitüsein', 'сейитягъя' => 'seyityağya', |
198 | 'сейитягья' => 'seyityagya', 'сейитяхья' => 'seyityahya', 'сейитяя' => 'seyityaya', |
199 | 'сеитумер' => 'seitümer', 'сеитусеин' => 'seitüsein', 'сеитягъя' => 'seityağya', |
200 | 'сеитягья' => 'seityagya', 'сеитяхья' => 'seityahya', 'сеитяя' => 'seityaya', |
201 | 'сурет' => 'süret', 'увертюра' => 'uvertüra', 'угле' => 'ugle', 'узвий' => 'uzviy', |
202 | 'улица' => 'ulitsa', 'ультимат' => 'ultimat', 'ультра' => 'ultra', 'ульянов' => 'ulyanov', |
203 | 'универ' => 'univer', 'уник' => 'unik', 'унис' => 'unis', 'унит' => 'unit', 'униф' => 'unif', |
204 | 'унтер' => 'unter', 'урьян' => 'uryan', 'утил' => 'util', 'уткин' => 'utkin', |
205 | 'учебн' => 'uçebn', 'шовини' => 'şovini', 'шоссе' => 'şosse', 'шубин' => 'şubin', |
206 | 'шунен' => 'şunen', 'шуннен' => 'şunnen', 'шунчюн' => 'şunçün', 'щёлкино' => 'şçolkino', |
207 | 'эмирусеин' => 'emirüsein', 'юзбашы' => 'yüzbaşı', 'юзйыл' => 'yüzyıl', 'юртер' => 'yurter', |
208 | 'ющенко' => 'yuşçenko', |
209 | |
210 | ### Carefully ordered many-to-one mappings |
211 | # these are ordered so L2C is correct (the later Cyrillic one) |
212 | # see also $ManyToOneC2LMappings above for C2L |
213 | 'шофер' => 'şoför', 'шофёр' => 'şoför', |
214 | 'бугун' => 'bugün', 'бугунь' => 'bugün', |
215 | 'демирёл' => 'demiryol', 'демиръёл' => 'demiryol', |
216 | 'гонъюл' => 'göñül', 'гонъюль' => 'göñül', |
217 | 'коккоз' => 'kökköz', 'коккозь' => 'kökköz', |
218 | 'корбекул' => 'körbekül', 'корьбекул' => 'körbekül', 'корьбекуль' => 'körbekül', |
219 | 'муур' => 'müür', 'муурь' => 'müür', |
220 | 'оригинал' => 'original', 'оригиналь' => 'original', |
221 | 'пускю' => 'püskü', 'пуськю' => 'püskü', |
222 | 'къарагоз' => 'qaragöz', 'къарагозь' => 'qaragöz', |
223 | |
224 | #### Latin to Cyrillic (deduped from above) |
225 | |
226 | # слова на -аль |
227 | # words in -аль |
228 | 'актуаль' => 'aktual', 'диагональ' => 'diagonal', 'документаль' => 'dokumental', |
229 | 'эмсаль' => 'emsal', 'фааль' => 'faal', 'феодаль' => 'feodal', 'фестиваль' => 'festival', |
230 | 'горизонталь' => 'gorizontal', 'хроникаль' => 'hronikal', 'идеаль' => 'ideal', |
231 | 'инструменталь' => 'instrumental', 'икъмаль' => 'iqmal', 'икъбаль' => 'iqbal', |
232 | 'истикъбаль' => 'istiqbal', 'истикъляль' => 'istiqlâl', 'италия' => 'italiya', |
233 | 'италья' => 'italya', 'ишгъаль' => 'işğal', 'кафедраль' => 'kafedral', 'казуаль' => 'kazual', |
234 | 'коллегиаль' => 'kollegial', 'колоссаль' => 'kolossal', 'коммуналь' => 'kommunal', |
235 | 'кординаль' => 'kordinal', 'криминаль' => 'kriminal', 'легаль' => 'legal', |
236 | 'леталь' => 'letal', 'либераль' => 'liberal', 'локаль' => 'lokal', |
237 | 'магистраль' => 'magistral', 'материаль' => 'material', 'машиналь' => 'maşinal', |
238 | 'меаль' => 'meal', 'медальон' => 'medalyon', 'медаль' => 'medal', |
239 | 'меридиональ' => 'meridional', 'мешъаль' => 'meşal', 'минераль' => 'mineral', |
240 | 'минималь' => 'minimal', 'мисаль' => 'misal', 'модаль' => 'modal', 'музыкаль' => 'muzıkal', |
241 | 'номиналь' => 'nominal', 'нормаль' => 'normal', 'оптималь' => 'optimal', |
242 | 'орбиталь' => 'orbital', 'педаль' => 'pedal', 'пропорциональ' => 'proportsional', |
243 | 'профессиональ' => 'professional', 'радикаль' => 'radikal', 'рациональ' => 'ratsional', |
244 | 'реаль' => 'real', 'региональ' => 'regional', 'суаль' => 'sual', 'шималь' => 'şimal', |
245 | 'территориаль' => 'territorial', 'тимсаль' => 'timsal', 'тоталь' => 'total', |
246 | 'уникаль' => 'unikal', 'универсаль' => 'universal', 'вертикаль' => 'vertikal', |
247 | 'виртуаль' => 'virtual', 'визуаль' => 'vizual', 'вуаль' => 'vual', 'зональ' => 'zonal', |
248 | 'зуаль' => 'zual', 'италь' => 'ital', |
249 | |
250 | # слова с мягким знаком перед а, о, у, э |
251 | # Words with a soft sign before а, о, у, э |
252 | 'бильакис' => 'bilakis', 'маальэсеф' => 'maalesef', 'мельун' => 'melun', 'озьара' => 'özara', |
253 | 'вельасыл' => 'velasıl', 'ельаякъ' => 'yelayaq', |
254 | |
255 | # другие слова с мягким знаком |
256 | # Other words with a soft sign |
257 | 'альбатрос' => 'albatros', 'альбинос' => 'albinos', 'альбом' => 'albom', |
258 | 'альбумин' => 'albumin', 'алфавит' => 'alfavit', 'альфа' => 'alfa', 'альманах' => 'almanah', |
259 | 'альпинист' => 'alpinist', 'альтерн' => 'altern', 'альтру' => 'altru', |
260 | 'альвеола' => 'alveola', 'ансамбль' => 'ansambl', 'аньане' => 'anane', 'асфальт' => 'asfalt', |
261 | 'бальнео' => 'balneo', 'баарь' => 'baar', 'базальт' => 'bazalt', 'бинокль' => 'binokl', |
262 | 'девальв' => 'devalv', 'факульт' => 'fakult', 'фальсиф' => 'falsif', 'фольклор' => 'folklor', |
263 | 'гальван' => 'galvan', 'геральд' => 'gerald', 'женьшень' => 'jenşen', |
264 | 'инвентарь' => 'inventar', 'кальк' => 'kalk', 'кальмар' => 'kalmar', 'консульт' => 'konsult', |
265 | 'контроль' => 'kontrol', 'культур' => 'kultur', 'лагерь' => 'lager', 'макъбуль' => 'maqbul', |
266 | 'макъуль' => 'maqul', 'мальт' => 'malt', 'мальземе' => 'malzeme', 'меджуль' => 'mecul', |
267 | 'мешгуль' => 'meşgül', 'мешгъуль' => 'meşğul', 'мульти' => 'multi', |
268 | 'мусульман' => 'musulman', 'нефть' => 'neft', 'пальто' => 'palto', 'пароль' => 'parol', |
269 | 'патруль' => 'patrul', 'пенальти' => 'penalti', 'къальби' => 'qalbi', 'къальпке' => 'qalpke', |
270 | 'къальплер' => 'qalpler', 'къальпни' => 'qalpni', 'къальпте' => 'qalpte', 'къаарь' => 'qaar', |
271 | 'ресуль' => 'resul', 'рыцарь' => 'rıtsar', 'рояль' => 'royal', 'саарь' => 'saar', |
272 | 'спираль' => 'spiral', 'сульх' => 'sulh', 'сумбуль' => 'sumbul', 'суньий' => 'suniy', |
273 | 'темаюль' => 'temayul', 'шампунь' => 'şampun', 'вальс' => 'vals', 'вальц' => 'valts', |
274 | 'ведомость' => 'vedomost', 'зулькъарнейн' => 'zulqarneyn', 'январь' => 'yanvar', |
275 | 'февраль' => 'fevral', 'июнь' => 'iyün', 'сентябрь' => 'sentâbr', 'октябрь' => 'oktâbr', |
276 | 'ноябрь' => 'noyabr', 'декабрь' => 'dekabr', |
277 | |
278 | # слова с твёрдым знаком |
279 | # Words with a solid sign |
280 | 'бидъат' => 'bidat', 'бузъюрек' => 'buzyürek', 'атешъюрек' => 'ateşyürek', |
281 | 'алъянакъ' => 'alyanaq', 'инъекц' => 'inyekts', 'мефъум' => 'mefum', 'мешъум' => 'meşum', |
282 | 'объект' => 'obyekt', 'разъезд' => 'razyezd', 'субъект' => 'subyekt', 'хавъяр' => 'havyar', |
283 | 'ямъям' => 'yamyam', |
284 | |
285 | # слова с буквой щ |
286 | # words with щ |
287 | 'ящик' => 'yaşçik', 'мещан' => 'meşçan', |
288 | |
289 | # слова с ц |
290 | # words with ц |
291 | 'акциз' => 'aktsiz', 'ацет' => 'atset', 'блиц' => 'blits', 'бруцеллёз' => 'brutsellöz', |
292 | 'доцент' => 'dotsent', 'фармацевт' => 'farmatsevt', 'глицер' => 'glitser', |
293 | 'люцерна' => 'lütserna', 'лицей' => 'litsey', 'меццо' => 'metstso', 'наци' => 'natsi', |
294 | 'проце' => 'protse', 'рецеп' => 'retsep', 'реценз' => 'retsenz', 'теплица' => 'teplitsa', |
295 | 'вице' => 'vitse', 'швейцар' => 'şveytsar', 'богородиц' => 'bogorodits', |
296 | 'бруцел' => 'brutsel', 'дацюк' => 'datsük', 'доницетти' => 'donitsetti', |
297 | 'драцена' => 'dratsena', 'контрацеп' => 'kontratsep', 'коцюб' => 'kotsüb', |
298 | 'меценат' => 'metsenat', 'мицел' => 'mitsel', 'моцарт' => 'motsart', 'плац' => 'plats', |
299 | 'плацен' => 'platsen', 'прецедент' => 'pretsedent', 'прецес' => 'pretses', |
300 | 'прицеп' => 'pritsep', 'спец' => 'spets', 'троиц' => 'troits', 'шприц' => 'şprits', |
301 | 'эпицентр' => 'epitsentr', 'яценюк' => 'yatsenük', |
302 | |
303 | # слова с тс |
304 | # words with тс |
305 | 'агъартс' => 'ağarts', 'агъыртс' => 'ağırts', 'бильдиртс' => 'bildirts', 'битсин' => 'bitsin', |
306 | 'буюльтс' => 'büyülts', 'буютс' => 'büyüts', 'гебертс' => 'geberts', 'делиртс' => 'delirts', |
307 | 'эгрильтс' => 'egrilts', 'эксильтс' => 'eksilts', 'эшитс' => 'eşits', 'иритс' => 'irits', |
308 | 'иситс' => 'isits', 'ичиртс' => 'içirts', 'кертсин' => 'kertsin', 'кенишлетс' => 'kenişlets', |
309 | 'кийсетс' => 'kiysets', 'копюртс' => 'köpürts', 'косьтертс' => 'kösterts', |
310 | 'кучертс' => 'küçerts', 'кучюльтс' => 'küçülts', 'пертсин' => 'pertsin', 'къайтс' => 'qayts', |
311 | 'къутсуз' => 'qutsuz', 'орьтс' => 'örts', 'отьс' => 'öts', 'тартс' => 'tarts', |
312 | 'тутсун' => 'tutsun', 'тюнъюльтс' => 'tüñülts', 'тюртс' => 'türts', 'янъартс' => 'yañarts', |
313 | 'ебертс' => 'yeberts', 'ешертс' => 'yeşerts', 'йиритс' => 'yirits', |
314 | |
315 | # разные исключения |
316 | # different exceptions |
317 | 'бюджет' => 'bücet', 'бюллет' => 'büllet', 'бюро' => 'büro', 'бюст' => 'büst', |
318 | 'диалог' => 'dialog', 'ханымэфенди' => 'hanımefendi', 'каньон' => 'kanyon', |
319 | 'кирил' => 'kiril', 'кирилл' => 'kirill', 'кёрджа' => 'körca', 'коy' => 'köy', |
320 | 'кулеръюзь' => 'küleryüz', 'маалле' => 'маальle', 'майор' => 'mayor', 'маниал' => 'manиаль', |
321 | 'нормала' => 'нормальa', 'проект' => 'proekt', 'район' => 'rayon', 'сойады' => 'soyadı', |
322 | 'спортсмен' => 'sportsmen', 'услюп' => 'üslüp', 'услюб' => 'üslüb', 'вакъиал' => 'vaqиаль', |
323 | 'юзйыллыкъ' => 'yüzyıllıq', 'койот' => 'koyot', |
324 | |
325 | # имена собственные |
326 | # proper names |
327 | 'адольф' => 'adolf', 'альберт' => 'albert', 'бешуй' => 'beşüy', 'флотск' => 'flotsk', |
328 | 'гайана' => 'gayana', 'грэсовский' => 'gresovskiy', 'гриц' => 'grits', 'гурджи' => 'gürci', |
329 | 'игорь' => 'igor', 'ильич' => 'ilyiç', 'ильин' => 'ilyin', 'исмаил' => 'ismail', |
330 | 'киттс' => 'kitts', 'комсомольск' => 'komsomolsk', 'корьбекулю' => 'körbekülü', |
331 | 'куницын' => 'kunitsın', 'львив' => 'lviv', 'львов' => 'lvov', 'марьино' => 'maryino', |
332 | 'махульдюр' => 'mahuldür', 'павел' => 'pavel', 'пантикапейон' => 'pantikapeyon', |
333 | 'къуртсейит' => 'qurtseyit', 'къуртсеит' => 'qurtseit', 'смаил' => 'smail', |
334 | 'советск' => 'sovetsk', 'шемьи-заде' => 'şemi-zade', 'тсвана' => 'tsvana', |
335 | 'учьэвли' => 'üçevli', 'йохан' => 'yohan', 'йорк' => 'york', 'винныця' => 'vinnıtsâ', |
336 | 'винница' => 'vinnitsa', 'хмельницк' => 'hmelnitsk', 'хмельныцк' => 'hmelnıtsk', |
337 | 'зайце' => 'zaytse', 'чистеньк' => 'çistenk', 'кольчуг' => 'kolçug', 'ручьи' => 'ruçyi', |
338 | 'ботсвана' => 'botsvana', 'большой' => 'bolşoy', 'большое' => 'bolşoye', |
339 | 'большая' => 'bolşaya', 'ущелье' => 'uşçelye', 'ущельное' => 'uşçelnoye', |
340 | 'предущельное' => 'preduşçelnoye', 'новенькое' => 'novenkoye', 'новосельц' => 'novoselts', |
341 | 'мелко' => 'melko', 'овощ' => 'ovoşç', 'перепёлк' => 'perepölk', 'рощин' => 'roşçin', |
342 | 'братск' => 'bratsk', 'краснофлотск' => 'krasnoflotsk', 'синицин' => 'sinitsin', |
343 | 'синицын' => 'sinitsın', 'льгов' => 'lgov', 'желто' => 'jelto', 'жёлт' => 'jölt', |
344 | 'пермь' => 'perm', 'солдатск' => 'soldatsk', 'кольцо' => 'koltso', 'шелко' => 'şelko', |
345 | 'охотск' => 'ohotsk', 'марий эл' => 'mariy el', 'мариуполь' => 'mariupol', |
346 | 'белгород' => 'belgorod', 'иркутск' => 'irkutsk', 'Иркутск' => 'İrkutsk', 'орёл' => 'oröl', |
347 | 'рязанск' => 'râzansk', 'рязань' => 'râzan', 'тверск' => 'tversk', 'тверь' => 'tver', |
348 | 'ярославль' => 'yaroslavl', 'благовеще' => 'blagoveşçe', 'мальдив' => 'maldiv', |
349 | 'бальбек' => 'balbek', 'альчик' => 'alçik', 'харьков' => 'harkov', 'волынск' => 'volınsk', |
350 | 'волынь' => 'volın', |
351 | |
352 | ]; |
353 | |
354 | /** |
355 | * @var string[] map Cyrillic to Latin and back, simple string match only (no regex) |
356 | * no variants: map exactly as is |
357 | */ |
358 | private $exactCaseMappings = [ |
359 | # аббревиатуры |
360 | # abbreviations |
361 | 'ОБСЕ' => 'OBSE', 'КъМДж' => 'QMC', 'КъДж' => 'QC', 'КъАЭ' => 'QAE', 'ГъСМК' => 'ĞSMK', |
362 | 'ШСДжБ' => 'ŞSCB', 'КъМШСДж' => 'QMŞSC', 'КъАССР' => 'QASSR', 'КъДМПУ' => 'QDMPU', |
363 | 'КъМПУ' => 'QMPU', |
364 | ]; |
365 | |
366 | /** |
367 | * @var string[] map Cyrillic to Latin and back, match end of word |
368 | * variants: all lowercase, all uppercase, first letter capitalized |
369 | * "first letter capitalized" variant was in the source |
370 | * items with capture group refs (e.g., $1) are only mapped from the |
371 | * regex to the reference |
372 | */ |
373 | private $suffixMapping = [ |
374 | # originally C2L |
375 | 'иаль' => 'ial', 'нуль' => 'nul', 'кой' => 'köy', 'койнинъ' => 'köyniñ', 'койни' => 'köyni', |
376 | 'койге' => 'köyge', 'койде' => 'köyde', 'койдеки' => 'köydeki', 'койден' => 'köyden', |
377 | 'козь' => 'köz', '-юнджи' => '-ünci', '-юнджиде' => '-üncide', '-юнджиден' => '-ünciden', |
378 | |
379 | # originally L2C, here swapped |
380 | 'льная' => 'lnaya', 'льное' => 'lnoye', 'льный' => 'lnıy', 'льний' => 'lniy', |
381 | 'льская' => 'lskaya', 'льский' => 'lskiy', 'льское' => 'lskoye', 'ополь' => 'opol', |
382 | 'щее' => 'şçeye', 'щий' => 'şçiy', 'щая' => 'şçaya', 'цепс' => 'tseps', |
383 | |
384 | ]; |
385 | |
386 | /** |
387 | * @var string[] map Cyrillic to Latin and back, match beginning of word |
388 | * variants: all lowercase letters, all uppercase letters, first letter capitalized |
389 | * items with capture group refs (e.g., $1) are only mapped from the |
390 | * regex to the reference |
391 | */ |
392 | private $prefixMapping = [ |
393 | # originally C2L |
394 | 'буюк([^ъ])' => 'büyük$1', 'бую([гдйлмнпрстчшc])(и)' => 'büyü$1$2', |
395 | 'буют([^ыа])' => 'büyüt$1', 'джонк([^ъ])' => 'cönk$1', 'коюм' => 'köyüm', 'коюнъ' => 'köyüñ', |
396 | 'коюн([ди])' => 'köyün$1', 'куе' => 'küye', 'куркке' => 'kürkke', 'куркни' => 'kürkni', |
397 | 'куркте' => 'kürkte', 'куркчю' => 'kürkçü', 'кою' => 'köyü', |
398 | 'жизнь' => 'jizn', |
399 | |
400 | # арабизмы на муи- муэ- / Arabic муи- муэ- |
401 | 'му([иэИЭ])' => 'mü$1', |
402 | |
403 | # originally L2C, here swapped |
404 | 'роль$1' => 'rol([^ü]|' . self::WB . ')', |
405 | 'усть$1' => 'üst([^ü]|' . self::WB . ')', |
406 | |
407 | # more prefixes |
408 | 'ком-кок' => 'köm-kök', |
409 | |
410 | ]; |
411 | |
412 | private $Cyrl2LatnRegexes = []; |
413 | private $Latn2CyrlRegexes = []; |
414 | |
415 | private function loadRegs() { |
416 | // Regexes as keys need to be declared in a function. |
417 | $this->Cyrl2LatnRegexes = [ |
418 | # относятся ко всему слову |
419 | # whole words |
420 | |
421 | // TODO: refactor upper/lower/first capital whole words without |
422 | // regexes into simpler list |
423 | |
424 | '/' . self::WB . 'КъЮШ' . self::WB . '/u' => 'QYŞ', |
425 | '/' . self::WB . 'ЮШ' . self::WB . '/u' => 'YŞ', |
426 | |
427 | '/' . self::WB . 'кок' . self::WB . '/u' => 'kök', |
428 | '/' . self::WB . 'Кок' . self::WB . '/u' => 'Kök', |
429 | '/' . self::WB . 'КОК' . self::WB . '/u' => 'KÖK', |
430 | '/' . self::WB . 'ком-кок' . self::WB . '/u' => 'köm-kök', |
431 | '/' . self::WB . 'Ком-кок' . self::WB . '/u' => 'Köm-kök', |
432 | '/' . self::WB . 'КОМ-КОК' . self::WB . '/u' => 'KÖM-KÖK', |
433 | |
434 | '/' . self::WB . 'коп' . self::WB . '/u' => 'köp', |
435 | '/' . self::WB . 'Коп' . self::WB . '/u' => 'Köp', |
436 | '/' . self::WB . 'КОП' . self::WB . '/u' => 'KÖP', |
437 | |
438 | '/' . self::WB . 'курк' . self::WB . '/u' => 'kürk', |
439 | '/' . self::WB . 'Курк' . self::WB . '/u' => 'Kürk', |
440 | '/' . self::WB . 'КУРК' . self::WB . '/u' => 'KÜRK', |
441 | |
442 | '/' . self::WB . 'ог' . self::WB . '/u' => 'ög', |
443 | '/' . self::WB . 'Ог' . self::WB . '/u' => 'Ög', |
444 | '/' . self::WB . 'ОГ' . self::WB . '/u' => 'ÖG', |
445 | |
446 | '/' . self::WB . 'юрип' . self::WB . '/u' => 'yürip', |
447 | '/' . self::WB . 'Юрип' . self::WB . '/u' => 'Yürip', |
448 | '/' . self::WB . 'ЮРИП' . self::WB . '/u' => 'YÜRİP', |
449 | |
450 | '/' . self::WB . 'юз' . self::WB . '/u' => 'yüz', |
451 | '/' . self::WB . 'Юз' . self::WB . '/u' => 'Yüz', |
452 | '/' . self::WB . 'ЮЗ' . self::WB . '/u' => 'YÜZ', |
453 | |
454 | '/' . self::WB . 'юк' . self::WB . '/u' => 'yük', |
455 | '/' . self::WB . 'Юк' . self::WB . '/u' => 'Yük', |
456 | '/' . self::WB . 'ЮК' . self::WB . '/u' => 'YÜK', |
457 | |
458 | '/' . self::WB . 'буюп' . self::WB . '/u' => 'büyüp', |
459 | '/' . self::WB . 'Буюп' . self::WB . '/u' => 'Büyüp', |
460 | '/' . self::WB . 'БУЮП' . self::WB . '/u' => 'BÜYÜP', |
461 | |
462 | '/' . self::WB . 'буюк' . self::WB . '/u' => 'büyük', |
463 | '/' . self::WB . 'Буюк' . self::WB . '/u' => 'Büyük', |
464 | '/' . self::WB . 'БУЮК' . self::WB . '/u' => 'BÜYÜK', |
465 | |
466 | '/' . self::WB . 'джонк' . self::WB . '/u' => 'cönk', |
467 | '/' . self::WB . 'Джонк' . self::WB . '/u' => 'Cönk', |
468 | '/' . self::WB . 'ДЖОНК' . self::WB . '/u' => 'CÖNK', |
469 | '/' . self::WB . 'джонкю' . self::WB . '/u' => 'cönkü', |
470 | '/' . self::WB . 'Джонкю' . self::WB . '/u' => 'Cönkü', |
471 | '/' . self::WB . 'ДЖОНКЮ' . self::WB . '/u' => 'CÖNKÜ', |
472 | |
473 | '/' . self::WB . 'куркчи/u' => 'kürkçi', |
474 | '/' . self::WB . 'Куркчи/u' => 'Kürkçi', |
475 | '/' . self::WB . 'КУРКЧИ/u' => 'KÜRKÇI', |
476 | |
477 | '/' . self::WB . 'устке' . self::WB . '/u' => 'üstke', |
478 | '/' . self::WB . 'Устке' . self::WB . '/u' => 'Üstke', |
479 | '/' . self::WB . 'УСТКЕ' . self::WB . '/u' => 'ÜSTKE', |
480 | '/' . self::WB . 'устте' . self::WB . '/u' => 'üstte', |
481 | '/' . self::WB . 'Устте' . self::WB . '/u' => 'Üstte', |
482 | '/' . self::WB . 'УСТТЕ' . self::WB . '/u' => 'ÜSTTE', |
483 | '/' . self::WB . 'усттен' . self::WB . '/u' => 'üstten', |
484 | '/' . self::WB . 'Усттен' . self::WB . '/u' => 'Üstten', |
485 | '/' . self::WB . 'УСТТЕН' . self::WB . '/u' => 'ÜSTTEN', |
486 | |
487 | # отдельно стоящие Ё и Я |
488 | # stand-alone Ё and Я |
489 | '/' . self::WB . 'Я' . self::WB . '/u' => 'Ya', |
490 | '/' . self::WB . 'Ё' . self::WB . '/u' => 'Yo', |
491 | |
492 | # относятся к началу слова |
493 | # word prefixes |
494 | '/' . self::WB . 'КъЮШн/u' => 'QYŞn', |
495 | '/' . self::WB . 'ЮШн/u' => 'YŞn', |
496 | |
497 | # need to convert digraphs (гъ, къ, нъ, дж) now to match patterns |
498 | '/гъ/u' => 'ğ', |
499 | '/Г[ъЪ]/u' => 'Ğ', |
500 | '/къ/u' => 'q', |
501 | '/К[ъЪ]/u' => 'Q', |
502 | '/нъ/u' => 'ñ', |
503 | '/Н[ъЪ]/u' => 'Ñ', |
504 | '/дж/u' => 'c', |
505 | '/Д[жЖ]/u' => 'C', |
506 | |
507 | # о => ö |
508 | '/' . self::WB . '([' . Crh::C_M_CONS . '])о([' . Crh::C_CONS . '])([' . Crh::C_CONS . |
509 | '])([еиэюьü])/u' => '$1ö$2$3$4', |
510 | '/' . self::WB . 'о([' . Crh::C_CONS . '])([' . Crh::C_CONS . '])([еиэюьü])/u' => 'ö$1$2$3', |
511 | '/' . self::WB . '([' . Crh::C_M_CONS . '])О([' . Crh::C_CONS . '])([' . Crh::C_CONS . |
512 | '])([еиэюьüЕИЭЮЬÜ])/u' => '$1Ö$2$3$4', |
513 | '/' . self::WB . 'О([' . Crh::C_CONS . '])([' . Crh::C_CONS . '])([еиэюьüЕИЭЮЬÜ])/u' |
514 | => 'Ö$1$2$3', |
515 | |
516 | '/' . self::WB . '([' . Crh::C_M_CONS . '])о([' . Crh::C_CONS . '])([еиэюьü])/u' => '$1ö$2$3', |
517 | '/' . self::WB . 'о([' . Crh::C_CONS . '])([еиэюьü])/u' => 'ö$1$2', |
518 | '/' . self::WB . '([' . Crh::C_M_CONS . '])О([' . Crh::C_CONS . '])([еиэюьüЕИЭЮЬÜ])/u' |
519 | => '$1Ö$2$3', |
520 | '/' . self::WB . 'О([' . Crh::C_CONS . '])([еиэюьüЕИЭЮЬÜ])/u' => 'Ö$1$2', |
521 | |
522 | # ё => yö |
523 | '/' . self::WB . 'ё([' . Crh::C_CONS . '])([' . Crh::C_CONS . '])([ьеюü])/u' => 'yö$1$2$3', |
524 | '/' . self::WB . 'Ё([' . Crh::C_CONS_LC . '])([' . Crh::C_CONS_LC . '])([ьеюü])/u' => 'Yö$1$2$3', |
525 | '/' . self::WB . 'Ё([' . Crh::C_CONS_UC . '])([' . Crh::C_CONS_UC . '])([ЬЕЮÜ])/u' => 'YÖ$1$2$3', |
526 | '/' . self::WB . 'ё([' . Crh::C_CONS . '])([ьеюü])/u' => 'yö$1$2', |
527 | '/' . self::WB . 'Ё([' . Crh::C_CONS_LC . '])([ьеюü])/u' => 'Yö$1$2', |
528 | '/' . self::WB . 'Ё([' . Crh::C_CONS_UC . '])([ЬЕЮÜ])/u' => 'YÖ$1$2', |
529 | |
530 | # у => ü, ую => üyü |
531 | '/' . self::WB . '([' . Crh::C_M_CONS . '])у([' . Crh::C_CONS . '])([' . Crh::C_CONS . |
532 | '])([еиэюьü])/u' => '$1ü$2$3$4', |
533 | '/' . self::WB . 'у([' . Crh::C_CONS . '])([' . Crh::C_CONS . '])([еиэюьü])/u' => 'ü$1$2$3', |
534 | '/' . self::WB . 'ую([' . Crh::C_CONS . '])([' . Crh::C_CONS . '])([еиэюьü])/u' => 'üyü$1$2$3', |
535 | '/' . self::WB . '([' . Crh::C_M_CONS . '])У([' . Crh::C_CONS . '])([' . Crh::C_CONS . |
536 | '])([еиэюьüЕИЭЮЬÜ])/u' => '$1Ü$2$3$4', |
537 | '/' . self::WB . 'У([' . Crh::C_CONS . '])([' . Crh::C_CONS . '])([еиэюьüЕИЭЮЬÜ])/u' |
538 | => 'Ü$1$2$3', |
539 | '/' . self::WB . 'Ую([' . Crh::C_CONS . '])([' . Crh::C_CONS . '])([еиэюьü])/u' => 'Üyü$1$2$3', |
540 | '/' . self::WB . 'УЮ([' . Crh::C_CONS . '])([' . Crh::C_CONS . '])([еиэюьü])/u' => 'ÜYÜ$1$2$3', |
541 | |
542 | '/' . self::WB . '([' . Crh::C_M_CONS . '])у([' . Crh::C_CONS . '])([еиэюьü])/u' => '$1ü$2$3', |
543 | '/' . self::WB . 'у([' . Crh::C_CONS . '])([еиэюьü])/u' => 'ü$1$2', |
544 | '/' . self::WB . 'ую([' . Crh::C_CONS . '])([еиэюьü])/u' => 'üyü$1$2', |
545 | '/' . self::WB . '([' . Crh::C_M_CONS . '])У([' . Crh::C_CONS . '])([еиэюьüЕИЭЮЬÜ])/u' |
546 | => '$1Ü$2$3', |
547 | '/' . self::WB . 'У([' . Crh::C_CONS . '])([еиэюьüЕИЭЮЬÜ])/u' => 'Ü$1$2', |
548 | '/' . self::WB . 'Ую([' . Crh::C_CONS . '])([еиэюьü])/u' => 'Üyü$1$2', |
549 | '/' . self::WB . 'УЮ([' . Crh::C_CONS . '])([еиэюьü])/u' => 'ÜYÜ$1$2', |
550 | |
551 | # ю => yü |
552 | '/' . self::WB . '([аыоуеиёюАЫОУЕИЁЮ]?)ю([' . Crh::C_CONS . '])([' . Crh::C_CONS . '])([ьеюü])/u' |
553 | => '$1yü$2$3$4', |
554 | '/' . self::WB . '([АЫОУЕИЁЮ]?)Ю([' . Crh::C_CONS_LC . '])([' . Crh::C_CONS_LC . '])([ьеюü])/u' |
555 | => '$1Yü$2$3$4', |
556 | '/' . self::WB . '([АЫОУЕИЁЮ]?)Ю([' . Crh::C_CONS_UC . '])([' . Crh::C_CONS_UC . '])([ЬЕЮÜ])/u' |
557 | => '$1YÜ$2$3$4', |
558 | '/' . self::WB . '([аыоуеиёюАЫОУЕИЁЮ]?)ю([' . Crh::C_CONS . '])([ьеюü])/u' => '$1yü$2$3', |
559 | '/' . self::WB . '([АЫОУЕИЁЮ]?)Ю([' . Crh::C_CONS_LC . '])([ьеюü])/u' => '$1Yü$2$3', |
560 | '/' . self::WB . '([АЫОУЕИЁЮ]?)Ю([' . Crh::C_CONS_UC . '])([ЬЕЮÜ])/u' => '$1YÜ$2$3', |
561 | |
562 | # e => ye, я => ya |
563 | '/' . self::WB . 'е/u' => 'ye', |
564 | '/' . self::WB . 'Е([' . Crh::C_LC . 'cğñqöü])/u' => 'Ye$1', |
565 | '/' . self::WB . 'Е([' . Crh::C_UC . 'CĞÑQÖÜ])/u' => 'YE$1', |
566 | '/' . self::WB . 'я/u' => 'ya', |
567 | '/' . self::WB . 'Я([' . Crh::C_LC . 'cğñqöü])/u' => 'Ya$1', |
568 | '/' . self::WB . 'Я([' . Crh::C_UC . 'CĞÑQÖÜ])/u' => 'YA$1', |
569 | '/([аеёиоуыэюяйьъaeöüАЕЁИОУЫЭЮЯЙЬЪAEÖÜ])е/u' => '$1ye', |
570 | '/([аеёиоуыэюяйьъaeöüАЕЁИОУЫЭЮЯЙЬЪAEÖÜ])Е([' . Crh::C_LC . 'cğñqöü])/u' => '$1Ye$2', |
571 | '/([аеёиоуыэюяйьъaeöüАЕЁИОУЫЭЮЯЙЬЪAEÖÜ])Е([' . Crh::C_UC . 'CĞÑQÖÜ])/u' => '$1YE$2', |
572 | '/([аеёиоуыэюяйьъaeöüğqАЕЁИОУЫЭЮЯЙЬЪAEÖÜĞQ])я/u' => '$1ya', |
573 | '/([аеёиоуыэюяйьъaeöüğqАЕЁИОУЫЭЮЯЙЬЪAEÖÜĞQ])Я([' . Crh::C_LC . 'cğñqöü])/u' => '$1Ya$2', |
574 | '/([аеёиоуыэюяйьъaeöüğqАЕЁИОУЫЭЮЯЙЬЪAEÖÜĞQ])Я([' . Crh::C_UC . 'CĞÑQÖÜ])/u' => '$1YA$2', |
575 | |
576 | # не зависят от места в слове |
577 | # position independent |
578 | |
579 | # слова на -льон |
580 | # words with -льон |
581 | '/льон/u' => 'lyon', |
582 | '/ЛЬОН/u' => 'LYON', |
583 | |
584 | '/козь([^я])/u' => 'köz$1', |
585 | '/Козь([^я])/u' => 'Köz$1', |
586 | '/КОЗЬ([^Я])/u' => 'KÖZ$1', |
587 | |
588 | # Ö, Ü 1-й заход: ё, ю после согласных > ö, ü |
589 | # Ö, Ü 1st instance: ё, ю after consonants > ö, ü |
590 | '/([' . Crh::C_CONS . '])ю/u' => '$1ü', |
591 | '/([' . Crh::C_CONS . '])Ю/u' => '$1Ü', |
592 | '/([' . Crh::C_CONS . '])ё/u' => '$1ö', |
593 | '/([' . Crh::C_CONS . '])Ё/u' => '$1Ö', |
594 | |
595 | # остальные вхождения о, у, ё, ю |
596 | # other occurrences of о, у, ё, ю |
597 | '/Ё([' . Crh::C_UC . 'CĞÑQÖÜ])/u' => 'YO$1', |
598 | '/Ю([' . Crh::C_UC . 'CĞÑQÖÜ])/u' => 'YU$1', |
599 | |
600 | # Ц & Щ |
601 | '/Ц([' . Crh::C_UC . 'CĞÑQÖÜ])/u' => 'TS$1', |
602 | '/Щ([' . Crh::C_UC . 'CĞÑQÖÜ])/u' => 'ŞÇ$1', |
603 | ]; |
604 | |
605 | $this->Latn2CyrlRegexes = [ |
606 | |
607 | // TODO: refactor upper/lower/first capital whole words without |
608 | // regexes into simpler list |
609 | |
610 | '/' . self::WB . 'an' . self::WB . '/u' => 'ань', |
611 | '/' . self::WB . 'An' . self::WB . '/u' => 'Ань', |
612 | '/' . self::WB . 'AN' . self::WB . '/u' => 'АНЬ', |
613 | '/' . self::WB . 'ange' . self::WB . '/u' => 'аньге', |
614 | '/' . self::WB . 'Ange' . self::WB . '/u' => 'Аньге', |
615 | '/' . self::WB . 'ANGE' . self::WB . '/u' => 'АНЬГЕ', |
616 | '/' . self::WB . 'ande' . self::WB . '/u' => 'аньде', |
617 | '/' . self::WB . 'Ande' . self::WB . '/u' => 'Аньде', |
618 | '/' . self::WB . 'ANDE' . self::WB . '/u' => 'АНЬДЕ', |
619 | '/' . self::WB . 'anki' . self::WB . '/u' => 'аньки', |
620 | '/' . self::WB . 'Anki' . self::WB . '/u' => 'Аньки', |
621 | '/' . self::WB . 'ANKİ' . self::WB . '/u' => 'АНЬКИ', |
622 | '/' . self::WB . 'deral' . self::WB . '/u' => 'деръал', |
623 | '/' . self::WB . 'Deral' . self::WB . '/u' => 'Деръал', |
624 | '/' . self::WB . 'DERAL' . self::WB . '/u' => 'ДЕРЪАЛ', |
625 | '/' . self::WB . 'kör' . self::WB . '/u' => 'кёр', |
626 | '/' . self::WB . 'Kör' . self::WB . '/u' => 'Кёр', |
627 | '/' . self::WB . 'KÖR' . self::WB . '/u' => 'КЁР', |
628 | '/' . self::WB . 'mer' . self::WB . '/u' => 'мэр', |
629 | '/' . self::WB . 'Mer' . self::WB . '/u' => 'Мэр', |
630 | '/' . self::WB . 'MER' . self::WB . '/u' => 'МЭР', |
631 | |
632 | '/' . self::WB . 'cönk/u' => 'джонк', |
633 | '/' . self::WB . 'Cönk/u' => 'Джонк', |
634 | '/' . self::WB . 'CÖNK/u' => 'ДЖОНК', |
635 | |
636 | # (y)etsin -> етсин/этсин |
637 | # note that target starts with CYRILLIC е/Е! |
638 | '/yetsin/u' => 'етсин', |
639 | '/Yetsin/u' => 'Етсин', |
640 | '/YETSİN/u' => 'ЕТСИН', |
641 | |
642 | # note that target starts with LATIN e/E! |
643 | # (other transformations will determine CYRILLIC е/э as needed) |
644 | '/etsin/u' => 'eтсин', |
645 | '/Etsin/u' => 'Eтсин', |
646 | '/ETSİN/u' => 'EТСИН', |
647 | |
648 | # буква Ё - первый заход |
649 | # расставляем Ь после согласных |
650 | '/' . self::WB . '([yY])ö([' . Crh::L_N_CONS . '])([aAuU' . Crh::L_CONS . ']|' . self::WB . ')/u' |
651 | => '$1ö$2ь$3', |
652 | '/' . self::WB . '([yY])Ö([' . Crh::L_N_CONS . '])([aAuU' . Crh::L_CONS . ']|' . self::WB . ')/u' |
653 | => '$1Ö$2Ь$3', |
654 | '/' . self::WB . 'AQŞ([^AEI]|' . self::WB . ')/u' => 'АКъШ$1', |
655 | |
656 | # буква Ю - первый заход |
657 | # расставляем Ь после согласных |
658 | '/' . self::WB . '([yY])ü([' . Crh::L_N_CONS . '])([aAuU' . Crh::L_CONS . ']|' . self::WB . ')/u' |
659 | => '$1ü$2ь$3', |
660 | '/' . self::WB . '([yY])Ü([' . Crh::L_N_CONS . '])([aAuU' . Crh::L_CONS . ']|' . self::WB . ')/u' |
661 | => '$1Ü$2Ь$3', |
662 | |
663 | '/' . self::WB . '([bcgkpşBCGKPŞ])ö([' . Crh::L_N_CONS . '])([' . Crh::L_CONS . ']|' . |
664 | self::WB . ')/u' => '$1ö$2ь$3', |
665 | '/' . self::WB . '([bcgkpşBCGKPŞ])Ö([' . Crh::L_N_CONS . '])([' . Crh::L_CONS . ']|' . |
666 | self::WB . ')/u' => '$1Ö$2Ь$3', |
667 | '/' . self::WB . '([bcgkpşBCGKPŞ])ü([' . Crh::L_N_CONS . '])([' . Crh::L_CONS . ']|' . |
668 | self::WB . ')/u' => '$1ü$2ь$3', |
669 | '/' . self::WB . '([bcgkpşBCGKPŞ])Ü([' . Crh::L_N_CONS . '])([' . Crh::L_CONS . ']|' . |
670 | self::WB . ')/u' => '$1Ü$2Ь$3', |
671 | |
672 | # ö и ü в начале слова |
673 | # случаи, когда нужен Ь |
674 | '/' . self::WB . 'ö([' . Crh::L_N_CONS . 'pP])([' . Crh::L_CONS . ']|' . self::WB . ')/u' |
675 | => 'ö$1ь$2', |
676 | '/' . self::WB . 'Ö([' . Crh::L_N_CONS_LC . 'p])([' . Crh::L_CONS . ']|' . self::WB . ')/u' |
677 | => 'Ö$1ь$2', |
678 | '/' . self::WB . 'Ö([' . Crh::L_N_CONS_UC . 'P])([' . Crh::L_CONS . ']|' . self::WB . ')/u' |
679 | => 'Ö$1Ь$2', |
680 | '/' . self::WB . 'ü([' . Crh::L_N_CONS . '])([' . Crh::L_CONS . ']|' . self::WB . ')/u' |
681 | => 'ü$1ь$2', |
682 | '/' . self::WB . 'Ü([' . Crh::L_N_CONS_LC . '])([' . Crh::L_CONS . ']|' . self::WB . ')/u' |
683 | => 'Ü$1ь$2', |
684 | '/' . self::WB . 'Ü([' . Crh::L_N_CONS_UC . '])([' . Crh::L_CONS . ']|' . self::WB . ')/u' |
685 | => 'Ü$1Ь$2', |
686 | |
687 | '/ts' . self::WB . '/u' => 'ц', |
688 | '/şç' . self::WB . '/u' => 'щ', |
689 | '/Ş[çÇ]' . self::WB . '/u' => 'Щ', |
690 | '/T[sS]' . self::WB . '/u' => 'Ц', |
691 | |
692 | # Ь после Л |
693 | # add Ь after Л |
694 | '/([' . Crh::L_F . '])l([' . Crh::L_CONS_LC . ']|' . self::WB . ')/u' => '$1ль$2', |
695 | '/([' . Crh::L_F_UC . '])L([' . Crh::L_CONS . ']|' . self::WB . ')/u' => '$1ЛЬ$2', |
696 | |
697 | # относятся к началу слова |
698 | '/' . self::WB . 'ts/u' => 'ц', |
699 | '/' . self::WB . 'T[sS]/u' => 'Ц', |
700 | |
701 | '/' . self::WB . 'şç/u' => 'щ', |
702 | '/' . self::WB . 'Ş[çÇ]/u' => 'Щ', |
703 | |
704 | # Э |
705 | '/(' . self::WB . '|[' . Crh::L_VOW . 'аеэяАЕЭЯ])e/u' => '$1э', |
706 | '/(' . self::WB . '|[' . Crh::L_VOW_UC . 'АЕЭЯ])E/u' => '$1Э', |
707 | |
708 | '/' . self::WB . '([' . Crh::L_M_CONS . '])ö/u' => '$1о', |
709 | '/' . self::WB . '([' . Crh::L_M_CONS . '])Ö/u' => '$1О', |
710 | '/' . self::WB . '([' . Crh::L_M_CONS . '])ü/u' => '$1у', |
711 | '/' . self::WB . '([' . Crh::L_M_CONS . '])Ü/u' => '$1У', |
712 | |
713 | '/' . self::WB . 'ö/u' => 'о', |
714 | '/' . self::WB . 'Ö/u' => 'О', |
715 | '/' . self::WB . 'ü/u' => 'у', |
716 | '/' . self::WB . 'Ü/u' => 'У', |
717 | |
718 | # некоторые исключения |
719 | # some exceptions |
720 | '/maal([^e])/u' => 'мааль$1', |
721 | '/Maal([^e])/u' => 'Мааль$1', |
722 | '/MAAL([^E])/u' => 'МААЛЬ$1', |
723 | '/küf([^eü])/u' => 'куфь$1', |
724 | '/Küf([^eü])/u' => 'Куфь$1', |
725 | '/KÜF([^EÜ])/u' => 'КУФЬ$1', |
726 | '/köz([^eü])/u' => 'козь$1', |
727 | '/Köz([^eü])/u' => 'Козь$1', |
728 | '/KÖZ([^EÜ])/u' => 'КОЗЬ$1', |
729 | |
730 | # Punctuation |
731 | '/#|No\./u' => '№', |
732 | |
733 | # некоторые случаи употребления Ц |
734 | '/tsi([^zñ])/u' => 'ци$1', |
735 | '/T[sS][iİ]([^zZñÑ])/u' => 'ЦИ$1', |
736 | '/ts([ou])/u' => 'ц$1', |
737 | '/T[sS]([oOuU])/u' => 'Ц$1', |
738 | '/ts([' . Crh::L_CONS . '])/u' => 'ц$1', |
739 | '/T[sS]([' . Crh::L_CONS . '])/u' => 'Ц$1', |
740 | '/([' . Crh::L_CONS . '])ts/u' => '$1ц', |
741 | '/([' . Crh::L_CONS . '])T[sS]/u' => '$1Ц', |
742 | '/tsиал/u' => 'циал', |
743 | '/TSИАЛ/u' => 'ЦИАЛ', |
744 | |
745 | # убираем ьi |
746 | # remove ьi (note Cyrillic ь and Latin i) |
747 | '/[ьЬ]([iİ])/u' => '$1', |
748 | |
749 | # ya & ye |
750 | '/([' . Crh::L_CONS . '])ya/u' => '$1ья', |
751 | '/([' . Crh::L_CONS . '])Y[aA]/u' => '$1ЬЯ', |
752 | '/([' . Crh::L_CONS . '])ye/u' => '$1ье', |
753 | '/([' . Crh::L_CONS . '])Y[eE]/u' => '$1ЬЕ', |
754 | |
755 | # расставляем Ь перед Ё |
756 | # place Ь in front of Ё |
757 | '/([' . Crh::L_CONS . '])y[oö]/u' => '$1ьё', |
758 | '/([' . Crh::L_CONS . '])Y[oOöÖ]/u' => '$1ЬЁ', |
759 | # оставшиеся вхождения yo и yö |
760 | # remaining occurrences of yo and yö |
761 | '/y[oö]/u' => 'ё', |
762 | '/[yY][oOöÖ]/u' => 'Ё', |
763 | |
764 | # расставляем Ь перед Ю |
765 | # place Ь in front of Ю |
766 | '/([' . Crh::L_CONS . '])y[uü]/u' => '$1ью', |
767 | '/([' . Crh::L_CONS . '])Y[uUüÜ]/u' => '$1ЬЮ', |
768 | # оставшиеся вхождения yu и yü |
769 | # remaining occurrences of yu and yü |
770 | '/y[uü]/u' => 'ю', |
771 | '/[yY][uUüÜ]/u' => 'Ю', |
772 | |
773 | # убираем ьa |
774 | # remove ьa (note Cyrillic ь and Latin a) |
775 | '/[ьЬ]([aA])/u' => '$1', |
776 | |
777 | # дж |
778 | '/C([' . Crh::L_UC . Crh::C_UC . 'АЕЁЙОУЭЮЯ])/u' => 'ДЖ$1', |
779 | '/([' . Crh::L_UC . Crh::C_UC . 'АЕЁЙОУЭЮЯ])C/u' => '$1ДЖ', |
780 | |
781 | # гъ, къ, нъ |
782 | '/Ğ([' . Crh::L_UC . Crh::C_UC . '])/u' => 'ГЪ$1', |
783 | '/([' . Crh::L_UC . Crh::C_UC . 'Ъ])Ğ/u' => '$1ГЪ', |
784 | |
785 | '/Q([' . Crh::L_UC . Crh::C_UC . '])/u' => 'КЪ$1', |
786 | '/([' . Crh::L_UC . Crh::C_UC . 'Ъ])Q/u' => '$1КЪ', |
787 | |
788 | '/Ñ([' . Crh::L_UC . Crh::C_UC . '])/u' => 'НЪ$1', |
789 | '/([' . Crh::L_UC . Crh::C_UC . 'Ъ])Ñ/u' => '$1НЪ', |
790 | |
791 | ]; |
792 | } |
793 | |
794 | private $CyrlCleanUpRegexes = [ |
795 | '/([клнрст])ь\1/u' => '$1$1', |
796 | '/([КЛНРСТ])Ь\1/u' => '$1$1', |
797 | '/К[ьЬ]к/u' => 'Кк', |
798 | '/Л[ьЬ]л/u' => 'Лл', |
799 | '/Н[ьЬ]н/u' => 'Нн', |
800 | '/Р[ьЬ]р/u' => 'Рр', |
801 | '/С[ьЬ]с/u' => 'Сс', |
802 | '/Т[ьЬ]т/u' => 'Тт', |
803 | |
804 | # убираем ьы и ь..ы |
805 | # remove ьы и ь..ы |
806 | '/[ьЬ]ы/u' => 'ы', |
807 | '/ЬЫ/u' => 'Ы', |
808 | '/[ьЬ]([гдклмнпрстчшГДКЛМНПРСТЧШ])ы/u' => '$1ы', |
809 | '/Ь([гдклмнпрстчшГДКЛМНПРСТЧШ])Ы/u' => '$1Ы', |
810 | '/[ьЬ]([гкнГКН])([ъЪ])ы/u' => '$1$2ы', |
811 | '/Ь([ГКН])ЪЫ/u' => '$1ЪЫ', |
812 | |
813 | # убираем йь |
814 | # remove йь |
815 | '/йь/u' => 'й', |
816 | '/ЙЬ/u' => 'Й', |
817 | |
818 | # частичное решение проблемы слова юз - 100 |
819 | # Partial solution to the problem of the word юз ("100") |
820 | # notice that these are cross-word patterns |
821 | '/эки юзь/u' => 'эки юз', '/Эки юзь/u' => 'Эки юз', '/ЭКИ ЮЗЬ/u' => 'ЭКИ ЮЗ', |
822 | '/учь юзь/u' => 'учь юз', '/Учь юзь/u' => 'Учь юз', '/УЧЬ ЮЗЬ/u' => 'УЧЬ ЮЗ', |
823 | '/дёрт юзь/u' => 'дёрт юз', '/Дёрт юзь/u' => 'Дёрт юз', '/ДЁРТ ЮЗЬ/u' => 'ДЁРТ ЮЗ', |
824 | '/беш юзь/u' => 'беш юз', '/Беш юзь/u' => 'Беш юз', '/БЕШ ЮЗЬ/u' => 'БЕШ ЮЗ', |
825 | '/алты юзь/u' => 'алты юз', '/Алты юзь/u' => 'Алты юз', '/АЛТЫ ЮЗЬ/u' => 'АЛТЫ ЮЗ', |
826 | '/еди юзь/u' => 'еди юз', '/Еди юзь/u' => 'Еди юз', '/ЕДИ ЮЗЬ/u' => 'ЕДИ ЮЗ', |
827 | '/секиз юзь/u' => 'секиз юз', '/Секиз юзь/u' => 'Секиз юз', '/СЕКИЗ ЮЗЬ/u' => 'СЕКИЗ ЮЗ', |
828 | '/докъуз юзь/u' => 'докъуз юз', '/Докъуз юзь/u' => 'Докъуз юз', '/ДОКЪУЗ ЮЗЬ/u' => 'ДОКЪУЗ ЮЗ', |
829 | ]; |
830 | } |