所有分类
  • 所有分类
  • Html5资源
  • React资源
  • Vue资源
  • Php资源
  • ‌小程序资源
  • Python资源

2025年最火的中文搜索神器!pinyin-match 让AI应用秒懂中文拼音,Vue3/React项目必备

简介

pinyin-match 是一个轻量级的 JavaScript 拼音匹配库,支持中文拼音搜索和匹配。它可以将中文文本转换为拼音,并支持模糊匹配,特别适用于搜索功能、自动补全、数据过滤等场景。

主要特性

  • 🚀 轻量级: 压缩后仅约 20KB
  • 🎯 高性能: 基于优化的算法,快速匹配
  • 📝 中文支持: 完整的中文拼音转换
  • 🔍 模糊匹配: 支持拼音首字母、全拼、模糊匹配
  • 🌐 多音字支持: 智能处理多音字
  • 🔧 简单易用: 简洁的 API 设计

安装

# npm
npm install pinyin-match

# yarn
yarn add pinyin-match

# pnpm
pnpm add pinyin-match

基础用法

基本匹配

import pinyinMatch from "pinyin-match";

// 基础匹配
const result = pinyinMatch.match("你好世界", "nihao");
console.log(result); // true

// 首字母匹配
const result2 = pinyinMatch.match("你好世界", "nhsj");
console.log(result2); // true

// 混合匹配
const result3 = pinyinMatch.match("你好世界", "ni世界");
console.log(result3); // true

数组过滤

import pinyinMatch from "pinyin-match";

const data = [
  { name: "张三", age: 25 },
  { name: "李四", age: 30 },
  { name: "王五", age: 28 },
  { name: "赵六", age: 35 },
];

// 根据姓名拼音过滤
const filtered = data.filter((item) => pinyinMatch.match(item.name, "zhang"));
console.log(filtered); // [{ name: '张三', age: 25 }]

// 多条件匹配
const filtered2 = data.filter(
  (item) =>
    pinyinMatch.match(item.name, "li") || pinyinMatch.match(item.name, "李")
);
console.log(filtered2); // [{ name: '李四', age: 30 }]

获取匹配位置

import pinyinMatch from "pinyin-match";

// 获取匹配的详细信息
const result = pinyinMatch.match("你好世界", "ni", {
  returnMatchIndex: true,
});
console.log(result);
// {
//   matched: true,
//   index: 0,
//   length: 2
// }

高级功能

自定义匹配选项

import pinyinMatch from "pinyin-match";

const options = {
  // 是否忽略大小写
  caseSensitive: false,
  // 是否返回匹配位置
  returnMatchIndex: true,
  // 是否支持模糊匹配
  fuzzy: true,
};

const result = pinyinMatch.match("你好世界", "nhsj", options);
console.log(result);

批量处理

import pinyinMatch from "pinyin-match";

const cities = [
  "北京",
  "上海",
  "广州",
  "深圳",
  "杭州",
  "南京",
  "武汉",
  "成都",
  "西安",
  "重庆",
];

// 批量搜索
function searchCities(keyword) {
  return cities.filter((city) => pinyinMatch.match(city, keyword));
}

console.log(searchCities("beijing")); // ['北京']
console.log(searchCities("sh")); // ['上海', '深圳']
console.log(searchCities("bj")); // ['北京']

多音字处理

import pinyinMatch from "pinyin-match";

// 多音字自动处理
const result1 = pinyinMatch.match("重庆", "chongqing");
console.log(result1); // true

const result2 = pinyinMatch.match("重庆", "zhongqing");
console.log(result2); // true

const result3 = pinyinMatch.match("重庆", "cq");
console.log(result3); // true

实际应用场景

搜索组件

<template>
  <div class="search-container">
    <input
      v-model="keyword"
      placeholder="请输入搜索关键词..."
      class="search-input"
    />
    <div class="search-results">
      <div v-for="item in filteredData" :key="item.id" class="result-item">
        {{ item.name }}
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed } from "vue";
import pinyinMatch from "pinyin-match";

const keyword = ref("");
const data = ref([
  { id: 1, name: "张三" },
  { id: 2, name: "李四" },
  { id: 3, name: "王五" },
  { id: 4, name: "赵六" },
  { id: 5, name: "孙七" },
]);

const filteredData = computed(() => {
  if (!keyword.value) return data.value;

  return data.value.filter((item) =>
    pinyinMatch.match(item.name, keyword.value)
  );
});
</script>

自动补全组件

<template>
  <div class="autocomplete-container">
    <input
      v-model="inputValue"
      @input="handleInput"
      @focus="showDropdown = true"
      @blur="handleBlur"
      placeholder="请输入姓名..."
      class="autocomplete-input"
    />
    <div v-if="showDropdown && suggestions.length > 0" class="dropdown">
      <div
        v-for="suggestion in suggestions"
        :key="suggestion.id"
        @click="selectSuggestion(suggestion)"
        class="suggestion-item"
      >
        <span v-html="highlightMatch(suggestion.name, inputValue)"></span>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed } from "vue";
import pinyinMatch from "pinyin-match";

const inputValue = ref("");
const showDropdown = ref(false);
const data = ref([
  { id: 1, name: "张三" },
  { id: 2, name: "李四" },
  { id: 3, name: "王五" },
  { id: 4, name: "赵六" },
  { id: 5, name: "孙七" },
]);

const suggestions = computed(() => {
  if (!inputValue.value) return [];

  return data.value
    .filter((item) => pinyinMatch.match(item.name, inputValue.value))
    .slice(0, 5); // 限制显示数量
});

const handleInput = () => {
  showDropdown.value = true;
};

const handleBlur = () => {
  setTimeout(() => {
    showDropdown.value = false;
  }, 200);
};

const selectSuggestion = (suggestion) => {
  inputValue.value = suggestion.name;
  showDropdown.value = false;
};

const highlightMatch = (text, keyword) => {
  // 简单的匹配高亮实现
  if (!keyword) return text;

  const regex = new RegExp(`(${keyword})`, "gi");
  return text.replace(regex, "<mark>$1</mark>");
};
</script>

树形结构搜索

import pinyinMatch from "pinyin-match";

// 递归搜索树形结构
function searchTree(nodes, keyword) {
  const results = [];

  function traverse(node) {
    // 检查当前节点是否匹配
    if (pinyinMatch.match(node.name, keyword)) {
      results.push(node);
    }

    // 递归搜索子节点
    if (node.children && node.children.length > 0) {
      node.children.forEach((child) => traverse(child));
    }
  }

  nodes.forEach((node) => traverse(node));
  return results;
}

// 使用示例
const treeData = [
  {
    id: 1,
    name: "技术部",
    children: [
      { id: 11, name: "前端组", children: [] },
      { id: 12, name: "后端组", children: [] },
    ],
  },
  {
    id: 2,
    name: "产品部",
    children: [
      { id: 21, name: "产品设计组", children: [] },
      { id: 22, name: "用户体验组", children: [] },
    ],
  },
];

const searchResults = searchTree(treeData, "jishu");
console.log(searchResults); // [{ id: 1, name: '技术部', children: [...] }]

常见问题

多音字处理

问题: 某些多音字匹配不准确

解决方案:

// 自定义多音字映射
const customPinyinMap = {
  重: ["zhong", "chong"],
  长: ["chang", "zhang"],
};

// 扩展匹配函数
function customMatch(text, keyword) {
  // 先尝试标准匹配
  if (pinyinMatch.match(text, keyword)) return true;

  // 再尝试自定义映射
  for (const [char, pinyins] of Object.entries(customPinyinMap)) {
    if (text.includes(char)) {
      for (const pinyin of pinyins) {
        if (pinyinMatch.match(text.replace(char, pinyin), keyword)) {
          return true;
        }
      }
    }
  }

  return false;
}

特殊字符处理

问题: 包含特殊字符的文本匹配失败

解决方案:

// 预处理文本
function preprocessText(text) {
  return text
    .replace(/[^\u4e00-\u9fa5a-zA-Z0-9]/g, "") // 移除特殊字符
    .trim();
}

// 使用预处理后的文本进行匹配
const result = pinyinMatch.match(preprocessText("你好,世界!"), "nihao");

总结

pinyin-match 是一个功能强大且易用的中文拼音匹配库,特别适合需要中文搜索功能的项目。通过合理使用其 API 和优化策略,可以构建出高性能的中文搜索体验。

原文链接:https://code.ifrontend.net/archives/1005,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?