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