Created
May 12, 2015 21:09
-
-
Save pavel-voronin/5dfcc0882e8512188f00 to your computer and use it in GitHub Desktop.
Генератор имён российской военной техники
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Утилиты | |
/** | |
* Multibyte string replace implementation | |
* | |
* @param string $search | |
* @param string $replace | |
* @param string $subject | |
* @param int $limit | |
* @return string | |
*/ | |
function mb_replace($search, $replace, $subject, $limit = -1) | |
{ | |
return implode($replace, mb_split(preg_quote($search), $subject, $limit == -1 ? $limit : $limit + 1)); | |
} | |
/** | |
* UTF-8 chr() implementation | |
* @param int $intval | |
* @return string | |
*/ | |
function unichr($intval) | |
{ | |
return mb_convert_encoding(pack('n', $intval), 'UTF-8', 'UTF-16BE'); | |
} | |
/** | |
* UTF-8 ord() implementation | |
* @param string $u | |
* @return int | |
*/ | |
function uniord($u) | |
{ | |
$k = mb_convert_encoding($u, 'UCS-2LE', 'UTF-8'); | |
$k1 = ord(substr($k, 0, 1)); | |
$k2 = ord(substr($k, 1, 1)); | |
return $k2 * 256 + $k1; | |
} | |
function printJson($data) | |
{ | |
$data = (array) $data; | |
header('Content-Type: application/json'); | |
echo json_encode($data); | |
die; | |
} | |
// Бизнес-логика | |
/** | |
* Прочитать шаблоны из файла | |
* | |
* @param string $templatesFile Файл с шаблонами | |
* @return array Группы шаблонов | |
* @throws Exception | |
*/ | |
function readTemlates($templatesFile) | |
{ | |
$file = fopen($templatesFile, 'r'); | |
if(!$file) | |
throw new Exception("Cannot read $templatesFile"); | |
$templates = []; | |
$currentGroup = null; | |
while($line = fgets($file)) | |
{ | |
$line = rtrim($line); | |
if(mb_strlen(trim($line)) == 0) // пустая строка | |
continue; | |
if(preg_match('#^[\w:]+:$#ui', $line)) // именованная группа шаблонов | |
{ | |
$currentGroup = mb_substr($line, 0, -1); | |
if(isset($templates[$currentGroup])) | |
throw new Exception("Group $currentGroup already exists"); | |
$templates[$currentGroup] = []; | |
continue; | |
} | |
if(preg_match('#^\t[^\t]+$#', $line)) // шаблон | |
{ | |
$templates[$currentGroup][] = trim($line); | |
continue; | |
} | |
throw new Exception("Wrong syntax: $line"); | |
} | |
fclose($file); | |
return $templates; | |
} | |
/** | |
* Создать строку по случайному шаблону из указанной группы шаблонов | |
* | |
* @param string $templates Группы шаблонов | |
* @param string $group Группа шаблонов для генерации строки | |
* @return string Сгенерированная строка | |
* @throws Exception | |
*/ | |
function generateFromGroup($templates, $group) | |
{ | |
if(!isset($templates[$group])) | |
throw new Exception("There are no $group group in templates array"); | |
if(!count($templates[$group])) | |
throw new Exception("The $group group is empty"); | |
$string = $templates[$group][array_rand($templates[$group])]; | |
// псевдо regex диапазоны | |
if(preg_match_all('#\[(\w)\-(\w)\]\{(\d),(\d)\}#ui', $string, $regexRanges, PREG_SET_ORDER)) | |
foreach($regexRanges as $regexRange) | |
$string = mb_replace($regexRange[0], generateRegexRange($regexRange[1], $regexRange[2], (int) $regexRange[3], (int) $regexRange[4]), $string); | |
if(preg_match_all('#(' . implode('|', array_keys($templates)) . ')#', $string, $templatesIncludings, PREG_SET_ORDER)) | |
foreach($templatesIncludings as $templatesIncluding) | |
$string = mb_replace($templatesIncluding[0], generateFromGroup($templates, $templatesIncluding[0]), $string, 1); | |
return trim($string); | |
} | |
/** | |
* Создать строку по regex-like шаблону | |
* | |
* @param string $fromChar левая граница диапазона | |
* @param string $toChar правая граница диапазона | |
* @param string $minLength минимальная длина | |
* @param string $maxLength максимальная длина | |
* @return string Сгенерированная строка | |
* @throws Exception | |
*/ | |
function generateRegexRange($fromChar, $toChar, $minLength, $maxLength) | |
{ | |
$fromCharCode = uniord($fromChar); | |
$toCharCode = uniord($toChar); | |
if($fromCharCode > $toCharCode) | |
throw new Exception("Wrong regex range: fromChar is greater than toChar"); | |
$string = ''; | |
for($i = 0; $i < rand($minLength, $maxLength); $i++) | |
$string .= unichr($fromCharCode + rand(0, $toCharCode - $fromCharCode)); | |
return $string; | |
} | |
try | |
{ | |
$templates = readTemlates('templates.txt'); | |
$string = generateFromGroup($templates, 'Название'); | |
} | |
catch(Exception $e) | |
{ | |
printJson(['status' => 'error', 'message' => $e->getMessage()]); | |
} | |
echo printJson(['status' => 'ok', 'data' => $string]); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Число: | |
[0-9]{1,3} | |
Аббр: | |
[А-И]{1,2} | |
[К-Щ]{1,2} | |
[Э-Я]{1,2} | |
Номер: | |
Аббр-Число | |
Аббр-Число АббрАббр | |
Аббр-ЧислоАббр | |
АббрАббр-Число | |
Число | |
ЧислоАббрЧисло | |
ЧислоАббрЧислоАббр | |
Предмет: | |
Черпак | |
Дуля | |
Зомби | |
Цветы: | |
Фейхоа | |
Репей | |
Дуриан | |
Персона: | |
Чижык-Пыжик | |
Леголас | |
Обама | |
Место: | |
Кудыкина Гора | |
Мышкина Подмышка | |
Развесёлая | |
Название: | |
Номер Предмет | |
Номер Цветы | |
Номер Персона | |
Номер Место | |
Предмет | |
Цветы | |
Персона | |
Место |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment