(7)解析单词

这个类的功能比较重要,决定成功与否的功能,就是介绍里说的,要对用户提交的每一次查询进行正确的匹配和查询,比如:


b) a-z分类的文件夹下面分布着更为详细的分类文件,而且都是txt格式的

 c) 分类文件遵循一定的规律,比如a-b,c,d表示单词开头的第一个字母是a,第二个字母可能是b,c或者d

d) 如果分类文件是这样的,比如a-b,c,m~z表示第一个字母开头是a,第二个字母是b或者c,第三个字母是m~z这个范围

e) 如果分类文件是这样的,比如a-b~z,则表示第一个字母是a,第二个字母是b~z这个范围内的任何一个字母

f)如果分类文件是这样的,比如a-bc~z则表示第一个字母是a,第二个字母是b,第三个字母是c~z这个范围


<?php
require_once 'groupDicName.class.php';
require_once "storeWord.class.php";
class Check
{
	private $groupName=null;
	private $redis=null;
	public function __construct()
	{
		$this->groupName=new GroupDicName();
		$this->redis=new  StoreWord();
	}
	
			/*
				1) 待查询的单词的前两个字符和单词分类名能够完全匹配,比如:
							[64] => h-a

							[65] => h-b,c,d,e

							[66] => h-f,g,h,i

							[67] => h-j,k,l,m,n,o

							[68] => h-p,q,r,s,t,u,v,w,x,y,z

				2) 待查询的单词的第一个字符可以匹配,但第二个字符不能匹配,好比你输入的单词是以ms 开头,即表示不存在,比如:
							80] => m-a

							[81] => m-b,c,d,e

							[82] => m-f,g,h,i

							[83] => m-j,k,l,m,n,o

							[84] => m-p,z
				3) d待查询的单词可以匹配单词分类名,且但此分类名只有一个总分类时,比如:
							[144] => x

							[145] => y

							[146] => z


			*/
	public function matchDic($userInput='')
	{
		if(!empty($userInput))
		{
			$userInput=strtolower($userInput);
			$firstChar=substr($userInput, 0,1);
			$secondChar=substr($userInput, 1,1);
			
			$dicSort=trim($this->groupName->getIndex());
				//echo $dicSort; exit();
			$word=explode('#', $dicSort);
			
			if(strlen($userInput)>=2 && strlen($userInput)<3)
			{
				foreach($word as $val)
				{
					$val=trim($val);
					if($firstChar==substr($val,0,1))
					{
						$firstMatch[]=$val;
					}
				}
				if(count($firstMatch)==1)
				{
					return $firstMatch[0];
				}
				else if(count($firstMatch)>1)
				{
					//对分类索引进行排序,将包含单词范围的~放在最前面,进行特殊匹配
					//这样的弊端是有一定的效率损耗......
					//但能匹配每一种特殊情况.....
					
					usort($firstMatch, function($one, $two){
						if(strpos($one, '~')) return -1;
						else return 1;
					});
					//var_dump($firstMatch); exit();
					foreach($firstMatch as $word)
					{
						//匹配第1种情况,前两个字符都能匹配
						$set=substr($word,strpos($word, '-')+1);
						//var_dump($set); echo 'inner layer';exit();
						//echo $set."<br />";
						 if(preg_match('#^([a-z])~([a-z])#', $set, $match))
						{
							$startRange = $match[1];
							$endRange = $match[2];
							if( preg_match("#[$startRange-$endRange]#", $secondChar))
							{
								return $word;
							}
						}
						else if(gettype(strpos($set, $secondChar))=="integer" && strpos($set,'~')===false)
						{
							return $word;
						}
									
					}
							
				}
				else
				{
					die("请输入查询单词");
				}
						
			}
			else if(strlen($userInput)>=3 )
			{
				$thirdChar=substr($userInput, 2,1);
				$firstMatch=array();
				foreach($word as $val)
				{
					$val=trim($val);
					if($firstChar==substr($val,0,1))
					{
						$firstMatch[]=$val;
					}
				}
					//var_dump($firstMatch);exit();
						//匹配第三种情况
						if(count($firstMatch)==1)
						{
							return $firstMatch[0];
						}
						/* 此前遗漏掉一种情况, o~n 中的~表示一个范围,而此前直接把~转换成,号了,所以不够准确*/
						
						else if(count($firstMatch)>1)
						{
								//对分类索引进行排序,将包含单词范围的~放在最前面,进行特殊匹配
								//这样的弊端是有一定的效率损耗......
								//但能匹配每一种特殊情况.....
								//
								usort($firstMatch, function($one, $two){
									if(strpos($one, '~')) return -1;
									else return 1;
								});
								//var_dump($firstMatch); exit();
								foreach($firstMatch as $word)
								{
									//匹配第1种情况,前两个字符都能匹配
									$set=substr($word,strpos($word, '-')+1);
									
									 if(preg_match('#^([a-z])([a-z])~([a-z])#', $set, $match))
									{
										$startChar=$match[1];
										$startRange = $match[2];
										$endRange = $match[3];
										if(gettype(strpos($startChar, $secondChar))=="integer" && preg_match("#[$startRange-$endRange]#", $thirdChar))
										{
											return $word;
										}
									}
								 	else if(preg_match('#(?<![a-z])([a-z])~([a-z])#', $set, $match))
									{
										$startRange = $match[1];
										$endRange = $match[2];
										if(preg_match("#[$startRange-$endRange]#", $secondChar, $match))
										{
											return $word;
										}
									}
									else if( ($set[0]==$secondChar)&& gettype(strpos($set,'~'))=="integer")
									{
										if(preg_match('#(?<![a-z])([a-z])~([a-z])#', $set, $match))
										{
											$startRange = $match[1];
											$endRange = $match[2];
											if(preg_match("#[$startRange-$endRange]#", $thirdChar, $match))
											{
												return $word;
											}
										}
									}
									else if(gettype(strpos($set, $secondChar))=="integer" && strpos($set,'~')===false)
									{
										return $word;
									}
									
								}
						}
						else
						{
							die("请输入查询单词");
						}
			}
			else
			{
				return $userInput;
			}
		}
		else
		{
			die("请输入查询单词");
		}
			
	}
	
	public function ajaxMatch($userInput='')
	{
		$wordRange=$this->matchDic($userInput);
		$words = $this->redis->getAllWord($wordRange);
		//var_dump($words);exit();
		$match=array();
		foreach($words as $word)
		{
			if(stripos($word, $userInput) !== false)
			{
				$match[]=$word;
			}
		}
		if(count($match)>0)
		{
			usort($match, function($one, $two){
			if(strlen($one)<strlen($two)) return -1;
			if(strlen($one) == strlen($two)) return 0;
			if(strlen($one)> strlen($two)) return 1;
			});
			if(count($match)>=10)
			{
				return array_slice($match,0,10);
			}
			else
			{
				return $match;
			}
		}
		else
		{
			return array('没有匹配项');
		}
		
	}
}

/*  $check = new Check();
//echo $check->matchDic('cobal');
print_r($check->ajaxMatch('make_of')); */
?>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值