* adjust for pinyin.

This commit is contained in:
wangyidong
2016-12-09 09:38:13 +08:00
parent 0fe35cb5d2
commit 6150ee7b76
13 changed files with 26670 additions and 42633 deletions
+3 -8
View File
@@ -98,7 +98,7 @@ class html extends baseHTML
static public function select($name = '', $options = array(), $selectedItems = "", $attrib = "", $append = false)
{
global $app;
static $dataKeys = array();
static $dataKeys;
$options = (array)($options);
if($append and !isset($options[$selectedItems])) $options[$selectedItems] = $selectedItems;
@@ -113,13 +113,8 @@ class html extends baseHTML
$string = "<select name='$name' {$id} $attrib>\n";
/* The options. */
static $pinyin = null;
if(empty($pinyin))
{
$app->loadClass('pinyin', false);
helper::import(dirname(__DIR__) . '/pinyin/memoryfiledictloader.php');
$pinyin = new pinyin(new MemoryFileDictLoader(dirname(__DIR__) . '/pinyin/data/'));
}
static $pinyin;
if(empty($pinyin)) $pinyin = $app->loadClass('pinyin');
$joinOptions = '';
$sign = ' aNd ';
-84
View File
@@ -1,84 +0,0 @@
<?php
return array (
'万俟' => ' mò qí',
'尉迟' => ' yù chí',
'单于' => ' chán yú',
'不' => ' fǒu',
'沈' => ' shěn',
'称' => ' chēng',
'车' => ' chē',
'万' => ' wàn',
'汤' => ' tāng',
'阿' => ' ā',
'丁' => ' dīng',
'强' => ' qiáng',
'仇' => ' qiú',
'叶' => ' yè',
'阚' => ' kàn',
'乐' => ' yuè',
'乜' => ' niè',
'陆' => ' lù',
'殷' => ' yīn',
'牟' => ' móu',
'区' => ' ōu',
'宿' => ' sù',
'俞' => ' yú',
'余' => ' yú',
'齐' => ' qí',
'许' => ' xǔ',
'信' => ' xìn',
'无' => ' wú',
'浣' => ' wǎn',
'艾' => ' ài',
'浅' => ' qiǎn',
'烟' => ' yān',
'蓝' => ' lán',
'於' => ' yú',
'寻' => ' xún',
'殳' => ' shū',
'思' => ' sī',
'鸟' => ' niǎo',
'卜' => ' bǔ',
'单' => ' shàn',
'南' => ' nán',
'柏' => ' bǎi',
'朴' => ' piáo',
'繁' => ' pó',
'曾' => ' zēng',
'瞿' => ' qú',
'缪' => ' miào',
'石' => ' shí',
'冯' => ' féng',
'覃' => ' qín',
'幺' => ' yāo',
'种' => ' chóng',
'折' => ' shè',
'燕' => ' yān',
'纪' => ' jǐ',
'过' => ' guō',
'华' => ' huà',
'冼' => ' xiǎn',
'秘' => ' bì',
'重' => ' chóng',
'解' => ' xiè',
'那' => ' nā',
'和' => ' hé',
'贾' => ' jiǎ',
'塔' => ' tǎ',
'盛' => ' shèng',
'查' => ' zhā',
'盖' => ' gě',
'居' => ' jū',
'哈' => ' hǎ',
'的' => ' dē',
'薄' => ' bó',
'佴' => ' nài',
'六' => ' lù',
'都' => ' dū',
'翟' => ' zhái',
'扎' => ' zā',
'藏' => ' zàng',
'粘' => ' niàn',
'难' => ' nàn',
'若' => ' ruò',
);
+26656
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-35
View File
@@ -1,35 +0,0 @@
<?php
/*
* This file is part of the overtrue/pinyin.
*
* (c) 2016 overtrue <i@overtrue.me>
*/
/**
* Dict loader interface.
*/
interface DictLoaderInterface
{
/**
* Load dict.
*
* <pre>
* [
* '响应时间' => "[\t]xiǎng[\t]yìng[\t]shí[\t]jiān",
* '长篇连载' => '[\t]cháng[\t]piān[\t]lián[\t]zǎi',
* //...
* ]
* </pre>
*
* @param Closure $callback
*/
public function map(Closure $callback);
/**
* Load surname dict.
*
* @param Closure $callback
*/
public function mapSurname(Closure $callback);
}
-70
View File
@@ -1,70 +0,0 @@
<?php
/*
* This file is part of the overtrue/pinyin.
*
* (c) 2016 overtrue <i@overtrue.me>
*/
helper::import(__DIR__ . '/dictloaderinterface.php');
/**
* Dict File loader.
*/
class FileDictLoader implements DictLoaderInterface
{
/**
* Words segment name.
*
* @var string
*/
protected $segmentName = 'words_%s';
/**
* Dict path.
*
* @var string
*/
protected $path;
/**
* Constructor.
*
* @param string $path
*/
public function __construct($path)
{
$this->path = $path;
}
/**
* Load dict.
*
* @param Closure $callback
*/
public function map(Closure $callback)
{
for ($i = 0; $i < 100; ++$i) {
$segment = $this->path.'/'.sprintf($this->segmentName, $i);
if (file_exists($segment)) {
$dictionary = (array) include $segment;
$callback($dictionary);
}
}
}
/**
* Load surname dict.
*
* @param Closure $callback
*/
public function mapSurname(Closure $callback)
{
$surnames = $this->path.'/surnames';
if (file_exists($surnames)) {
$dictionary = (array) include $surnames;
$callback($dictionary);
}
}
}
-91
View File
@@ -1,91 +0,0 @@
<?php
/*
* This file is part of the overtrue/pinyin.
*
* (c) 2016 overtrue <i@overtrue.me>
*/
helper::import(__DIR__ . '/dictloaderinterface.php');
/**
* Memory Dict File loader.
*/
class MemoryFileDictLoader implements DictLoaderInterface
{
/**
* Data directory.
*
* @var string
*/
protected $path;
/**
* Words segment name.
*
* @var string
*/
protected $segmentName = 'words_%s';
/**
* Segment files.
*
* @var array
*/
protected $segments = array();
/**
* Surname cache.
*
* @var array
*/
protected $surnames = array();
/**
* Constructor.
*
* @param string $path
*/
public function __construct($path)
{
$this->path = $path;
for ($i = 0; $i < 100; ++$i) {
$segment = $path.'/'.sprintf($this->segmentName, $i);
if (file_exists($segment)) {
$this->segments[] = (array) include $segment;
}
}
}
/**
* Load dict.
*
* @param Closure $callback
*/
public function map(Closure $callback)
{
foreach ($this->segments as $dictionary) {
$callback($dictionary);
}
}
/**
* Load surname dict.
*
* @param Closure $callback
*/
public function mapSurname(Closure $callback)
{
if (empty($this->surnames)) {
$surnames = $this->path.'/surnames';
if (file_exists($surnames)) {
$this->surnames = (array) include $surnames;
}
}
$callback($this->surnames);
}
}
+11 -229
View File
@@ -5,60 +5,17 @@
*
* (c) 2016 overtrue <i@overtrue.me>
*/
helper::import(__DIR__ . '/filedictloader.php');
define('PINYIN_NONE', 'none');
define('PINYIN_ASCII', 'ascii');
define('PINYIN_UNICODE', 'unicode');
/**
* Chinese to pinyin translator.
*
* @author overtrue <i@overtrue.me>
* @copyright 2015 overtrue <i@overtrue.me>
*
* @link https://github.com/overtrue/pinyin
* @link http://overtrue.me
*/
class pinyin
{
const NONE = 'none';
const ASCII = 'ascii';
const UNICODE = 'unicode';
/**
* Dict loader.
*
* @var \Overtrue\Pinyin\DictLoaderInterface
*/
protected $loader;
/**
* Punctuations map.
*
* @var array
*/
protected $punctuations = array(
'' => ',',
'。' => '.',
'' => '!',
'' => '?',
'' => ':',
'“' => '"',
'”' => '"',
'' => "'",
'' => "'",
);
/**
* Constructor.
*
* @param \Overtrue\Pinyin\DictLoaderInterface $loader
*/
public function __construct(DictLoaderInterface $loader = null)
public function __construct()
{
$this->loader = $loader;
$this->segments = array();
$segment = __DIR__ . '/data/words';
if(file_exists($segment)) $this->segments = include __DIR__ . '/data/words';
}
/**
@@ -69,105 +26,13 @@ class pinyin
*
* @return array
*/
public function convert($string, $option = self::NONE)
public function convert($string)
{
$pinyin = $this->romanize($string);
return $this->splitWords($pinyin, $option);
$split = array_filter(preg_split('/[^a-z]+/iu', $pinyin));
return array_values($split);
}
/**
* Convert string (person name) to pinyin.
*
* @param string $stringName
* @param string $option
*
* @return array
*/
public function name($stringName, $option = self::NONE)
{
$pinyin = $this->romanize($stringName, true);
return $this->splitWords($pinyin, $option);
}
/**
* Return a pinyin permalink from string.
*
* @param string $string
* @param string $delimiter
*
* @return string
*/
public function permalink($string, $delimiter = '-')
{
if (!in_array($delimiter, array('_', '-', '.', ''), true)) {
throw new InvalidArgumentException("Delimiter must be one of: '_', '-', '', '.'.");
}
return implode($delimiter, $this->convert($string, false));
}
/**
* Return first letters.
*
* @param string $string
* @param string $delimiter
*
* @return string
*/
public function abbr($string, $delimiter = '')
{
return implode($delimiter, array_map(function ($pinyin) {
return $pinyin[0];
}, $this->convert($string, false)));
}
/**
* Chinese to pinyin sentense.
*
* @param string $sentence
* @param string $option
*
* @return string
*/
public function sentence($sentence, $withTone = false)
{
$marks = array_keys($this->punctuations);
$punctuationsRegex = preg_quote(implode(array_merge($marks, $this->punctuations)), '/');
$regex = '/[^üāēīōūǖáéíóúǘǎěǐǒǔǚàèìòùǜa-z0-9'.$punctuationsRegex.'\s_]+/iu';
$pinyin = preg_replace($regex, '', $this->romanize($sentence));
$punctuations = array_merge($this->punctuations, array("\t" => ' ', ' ' => ' '));
$pinyin = trim(str_replace(array_keys($punctuations), $punctuations, $pinyin));
return $withTone ? $pinyin : $this->format($pinyin, false);
}
/**
* Loader setter.
*
* @param \Overtrue\Pinyin\DictLoaderInterface $loader
*
* @return $this
*/
public function setLoader(DictLoaderInterface $loader)
{
$this->loader = $loader;
return $this;
}
/**
* Return dict loader,.
*
* @return \Overtrue\Pinyin\DictLoaderInterface
*/
public function getLoader()
{
return $this->loader ?: new FileDictLoader(__DIR__ . '/data/');
}
/**
* Preprocess.
@@ -178,11 +43,8 @@ class pinyin
*/
protected function prepare($string)
{
$string = preg_replace_callback('~[a-z0-9_-]+~i', function ($matches) {
return "\t".$matches[0];
}, $string);
return preg_replace("~[^\p{Han}\p{P}\p{Z}\p{M}\p{N}\p{L}\t]~u", '', $string);
$string = preg_replace_callback('/[a-z0-9_-]+/i', create_function('$matches', 'return "\t" . $matches[0];'), $string);
return preg_replace("/[^\p{Han}\p{P}\p{Z}\p{M}\p{N}\p{L}\t]/u", '', $string);
}
/**
@@ -193,90 +55,10 @@ class pinyin
*
* @return string
*/
protected function romanize($string, $isName = false)
protected function romanize($string)
{
$string = $this->prepare($string);
$dictLoader = $this->getLoader();
if ($isName) {
$string = $this->convertSurname($string, $dictLoader);
}
$dictLoader->map(function ($dictionary) use (&$string) {
$string = strtr($string, $dictionary);
});
$string = strtr($string, $this->segments);
return $string;
}
/**
* Convert Chinese Surname to pinyin.
*
* @param string $string
* @param \Overtrue\Pinyin\DictLoaderInterface $dictLoader
*
* @return string
*/
protected function convertSurname($string, $dictLoader)
{
$dictLoader->mapSurname(function ($dictionary) use (&$string) {
foreach ($dictionary as $surname => $pinyin) {
if (strpos($string, $surname) === 0) {
$string = $pinyin.mb_substr($string, mb_strlen($surname, 'UTF-8'), mb_strlen($string, 'UTF-8') - 1, 'UTF-8');
break;
}
}
});
return $string;
}
/**
* Split pinyin string to words.
*
* @param string $pinyin
* @param string $option
*
* @return array
*/
public function splitWords($pinyin, $option)
{
$split = array_filter(preg_split('/[^üāēīōūǖáéíóúǘǎěǐǒǔǚàèìòùǜa-z\d]+/iu', $pinyin));
if ($option !== self::UNICODE) {
foreach ($split as $index => $pinyin) {
$split[$index] = $this->format($pinyin, $option === self::ASCII);
}
}
return array_values($split);
}
/**
* Format.
*
* @param string $pinyin
* @param bool $tone
*
* @return string
*/
protected function format($pinyin, $tone = false)
{
$replacements = array(
'üē' => array('ue', 1), 'üé' => array('ue', 2), 'üě' => array('ue', 3), 'üè' => array('ue', 4),
'ā' => array('a', 1), 'ē' => array('e', 1), 'ī' => array('i', 1), 'ō' => array('o', 1), 'ū' => array('u', 1), 'ǖ' => array('v', 1),
'á' => array('a', 2), 'é' => array('e', 2), 'í' => array('i', 2), 'ó' => array('o', 2), 'ú' => array('u', 2), 'ǘ' => array('v', 2),
'ǎ' => array('a', 3), 'ě' => array('e', 3), 'ǐ' => array('i', 3), 'ǒ' => array('o', 3), 'ǔ' => array('u', 3), 'ǚ' => array('v', 3),
'à' => array('a', 4), 'è' => array('e', 4), 'ì' => array('i', 4), 'ò' => array('o', 4), 'ù' => array('u', 4), 'ǜ' => array('v', 4),
);
foreach ($replacements as $unicde => $replacements) {
if (false !== strpos($pinyin, $unicde)) {
$pinyin = str_replace($unicde, $replacements[0], $pinyin).($tone ? $replacements[1] : '');
}
}
return $pinyin;
}
}