- 論壇徽章:
- 0
|
需要注意的一些事情
本文使用的為 Java 語言解決方案。
搜索方法上,按照個人理解,有兩點關鍵:
將類似 “women” 這樣的詞分解成 “wo’men”。經(jīng)過這樣的分詞,在搜索時無論通過全拼音匹配,還是首字母匹配,處理起來都比較方便。
目前我接觸過的常見搜索場景有兩種,它們對詞庫的建立有如下影響:
1.通訊錄搜索
對詞庫有頻繁的添加 / 刪除操作。
2.站內搜索
使用預先維護好的詞庫。
如果是通訊錄搜索,可以在新建聯(lián)系人的時候,把聯(lián)系人的名字轉為拼音,存入數(shù)據(jù)庫中另一個記錄拼音的字段,在搜索的時候通過拼音來匹配。
如果是站內搜索,可以直接建立拼音詞庫,搜索的時候通過拼音來匹配。
實現(xiàn)
首先是詞庫的構建。毫無疑問,我們需要為詞庫建一張至少包含中文詞匯以及對應的拼音詞匯的表。
通訊錄搜索,可能會使用一些例如 pinyin4j 的第三方庫,將中文字轉換為拼音。當然也我們可以自己實現(xiàn)轉換拼音的功能,如果這樣做,則需要在代碼中設定好中文字庫和對應的拼音,同時特別注意多音字的處理。
下面是使用 pinyin4j 庫的例子。使用 pinyin4j 庫可以支持簡體 / 繁體中文轉換為拼音,而且支持帶聲調的格式化輸出。
我們使用 Maven 來添加 pinyin4j,在 pom.xml 中添加- <dependencies>
- <dependency>
- <groupId>com.belerweb</groupId>
- <artifactId>pinyin4j</artifactId>
- <version>2.5.0</version>
- </dependency>
- </dependencies>
復制代碼 實現(xiàn)類:- public class Chinese {
- private HanyuPinyinOutputFormat format = null;
- private String[] pinyin;
- public Chinese() {
- format = new HanyuPinyinOutputFormat();
- format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
- pinyin = null;
- }
- //轉換單個中文字符
- public String getCharacterPinYin(char c) {
- try {
- pinyin = PinyinHelper.toHanyuPinyinStringArray(c, format);
- } catch(BadHanyuPinyinOutputFormatCombination e) {
- e.printStackTrace();
- }
- // 如果c不是漢字,返回null
- if(null == pinyin)
- return null;
- // 多音字取第一個值
- return pinyin[0];
- }
- //轉換一個字符串
- public String getStringPinYin(String str) {
- StringBuilder sb = new StringBuilder();
- for(int i = 0; i < str.length(); ++i) {
- String tmp = getCharacterPinYin(str.charAt(i));
- if(null == tmp) {
- // 如果str.charAt(i)不是漢字,則保持原樣
- sb.append(str.charAt(i));
- } else {
- sb.append(tmp);
- //分詞
- if ( i < str.length() - 1 && null != getCharacterPinYin(str.charAt(i + 1))) {
- sb.append("\'");
- }
- }
- }
- return sb.toString().trim();
- }
- public static void main(String[] args) {
- Chinese chinese = new Chinese();
- String str = "哈哈,我愛 Coding";
- String pinYin = chinese.getStringPinYin(str);
- System.out.println(pinYin);
- }
- }
復制代碼 輸出的結果 每當有通訊錄聯(lián)系人更新時,采用上述方法更新數(shù)據(jù)庫中的拼音字段即可。
站內搜索,詞庫來源可以使用搜狗標準詞庫和細胞詞庫等。
搜狗標準詞庫
下載的搜狗詞庫可以使用深藍詞庫轉換器來轉換成 txt 文件,或者其他輸入法的標準格式。
深藍詞庫轉換 2.0
轉換為 txt 文件后,處理以后,修改成為 insert 語句,插入數(shù)據(jù)庫。
4.jpg (12.45 KB, 下載次數(shù): 27)
下載附件
2015-01-27 12:12 上傳
最后的關鍵,就是將輸入的拼音分詞,然后與數(shù)據(jù)庫中的拼音字段匹配,分詞采用正則表達式實現(xiàn)。
分詞實現(xiàn): - public class PinyinUtils {
- //分詞正則表達式
- public static String regEx = "[^aoeiuv]?h?[iuv]?(ai|ei|ao|ou|er|ang?|eng?|ong|a|o|e|i|u|ng|n)?";
- public static String split(String input) {
- int tag = 0;
- StringBuffer sb = new StringBuffer();
- String formatted = "";
- List<String> tokenResult = new ArrayList<String>();
- for (int i = input.length(); i > 0; i = i - tag) {
- Pattern pat = Pattern.compile(regEx);
- Matcher matcher = pat.matcher(input);
- boolean rs = matcher.find();
- sb.append(matcher.group());
- sb.append("\'");
- tag = matcher.end() - matcher.start();
- tokenResult.add(input.substring(0, 1));
- input = input.substring(tag);
- }
- if (sb.length() > 0) {
- formatted = sb.toString().substring(0, sb.toString().length() - 1);
- }
- return formatted;
- }
- public static void main(String[] args) {
- String str = "koudingboke";
- System.out.println(PinyinUtils.split(str));
- }
- }
復制代碼 輸出結果 根據(jù)此輸出結果,在詞庫中匹配即可。
根據(jù)以上方式搜索出的詞匯,會比較固定。如果有按照搜索頻率對搜索結果排序的需求,可以針對每個詞匯的查詢計數(shù)。具體實現(xiàn)這里不再贅述。
個人一點粗淺經(jīng)驗,歡迎各位大牛一起交流。
本文來自 Coding 官方技術博客(blog.coding.net),如需轉載請注明出處,謝謝。
QQ截圖20150127120042.jpg (18.33 KB, 下載次數(shù): 23)
下載附件
2015-01-27 12:15 上傳
|
|