数据集来源:
English Quotations (为kaggle公开数据集,txt格式)
中文诗歌数据集(为kaggle公开数据集,txt格式)
一、项目背景与目的
在我们对一片文章进行阅读时,有时候会对文章中的一些词汇感兴趣,并好奇它在文中的出现频率,所以我们以此为目的在kaggle上进行了一个文字检索的代码编写。
二、代码部分
1、四个依赖库
re:正则表达式处理
collections.Counter:高效计数器
chardet:编码自动检测
os:文件系统操作

2、 核心算法模块
def text_search_counter(file_path, search_terms, case_sensitive=False, whole_word=False):
text_search_counter函数负责实际的文本处理和统计

3、交互界面模块
def interactive_search():
interactive_search函数提供用户交互界面


4、运行结果

三 、框架与算法
编码检测框架(Chardet)
代码实现:chardet.detect(raw_data)
核心原理:
- 基于贝叶斯分类器(Naive Bayes)和特征工程,通过分析字节频率、字符分布等特征推测文本编码。
- 支持UTF-8、GBK、ISO-8859-1等常见编码。
优点:
- 自动化检测:无需用户指定编码即可读取文件。
- 高兼容性:覆盖主流编码格式,减少乱码问题。
- 轻量级:依赖库较小,适合嵌入脚本工具。
缺点:
- 准确性有限:短文本或混合编码场景可能误判。
- 性能损耗:需读取文件头部(如代码中的前10KB)进行分析。
- 无法处理极端情况:如加密文本或自定义编码。
适用场景:
- 多语言文本处理(如爬虫抓取不同编码的网页)。
- 日志文件分析(如混合UTF-8和GBK的日志)。
- 旧系统迁移(如处理遗留系统的非标准编码)。
交互式命令行框架(Interactive CLI)
代码实现:while True循环 + input()函数
核心原理:
- 基于事件驱动编程,通过循环监听用户输入并触发相应操作。
- 使用状态机管理文件路径、搜索参数等上下文。
优点:
- 低依赖性:无需图形界面即可运行。
- 易调试:可直接打印中间结果。
- 适合脚本场景:可集成到自动化流程中。
缺点:
- 交互体验有限:无法实现复杂UI(如表格、图表)。
- 输入验证繁琐:需手动处理各种边界情况。
- 扩展性差:添加新功能需修改核心循环逻辑。
适用场景:
- 快速原型开发(如MVP验证)。
- 系统管理工具(如服务器监控脚本)。
- 离线数据分析(如本地日志分析)。
正则表达式匹配算法(Regular Expression Matching)
代码实现:re.findall(pattern, text)
核心原理:
- 基于有限自动机(Finite Automaton)理论,通过预编译模式字符串生成状态机,对文本进行模式匹配。
- 支持通配符(
.)、量词(*,+,?)、字符集([a-z])、分组(())等操作。
优点:
- 灵活性高:可定义复杂匹配规则(如邮箱格式、URL模式)。
- 表达力强:一行正则表达式可替代数百行条件判断代码。
- 跨语言支持:几乎所有编程语言均内置正则表达式库。
缺点:
- 性能瓶颈:复杂正则表达式(如回溯陷阱)可能导致指数级时间复杂度。
- 可读性差:嵌套量词或贪婪匹配模式难以维护。
- 安全风险:未经验证的用户输入正则表达式可能引发ReDoS攻击。
适用场景:
- 结构化文本解析(如日志分析、HTML标签提取)。
- 输入验证(如邮箱、手机号格式校验)。
- 模糊搜索(如通配符
*匹配)。
四、代码总览
import re
from collections import Counter
import chardet
import os
def text_search_counter(file_path, search_terms, case_sensitive=False, whole_word=False):
word_counts = Counter()
try:
# 自动检测文件编码
with open(file_path, 'rb') as f:
raw_data = f.read(10000)
encoding = chardet.detect(raw_data)['encoding'] or 'utf-8'
# 根据检测结果读取文件
with open(file_path, 'r', encoding=encoding, errors='ignore') as f:
text = f.read()
# 预处理文本
if not case_sensitive:
text = text.lower()
search_terms = [term.lower() for term in search_terms]
# 正则表达式模式生成
def create_pattern(term):
if whole_word:
return f"{re.escape(term)}"
else:
return re.escape(term)
patterns = [create_pattern(term) for term in search_terms]
# 统计所有匹配项
for pattern in patterns:
matches = re.findall(pattern, text)
word_counts[pattern] = len(matches)
except Exception as e:
print(f"错误:{str(e)}")
return None
return dict(word_counts)
def interactive_search():
file_path = None
while True:
try:
# 只在首次循环时选择文件
if not file_path:
# 获取文件路径
file_path = input("\n请输入要分析的文本文件路径(输入q退出):\n").strip()
if file_path.lower() == 'q':
print("退出程序")
return
# 验证文件是否存在
if not os.path.exists(file_path):
print("错误:输入的文件路径不存在!")
continue
# 获取搜索词输入
search_input = input("请输入要搜索的关键词(多个关键词用空格分隔,输入q退出):\n").strip()
if search_input.lower() == 'q':
print("退出程序")
return
search_terms = [term.strip() for term in search_input.split()]
# 验证搜索词
if not search_terms:
print("错误:未输入任何搜索关键词!")
continue
# 大小写敏感设置
case_sensitive = input("是否区分大小写?(y/n):\n").lower() == 'y'
# 完整单词匹配设置
whole_word = input("是否完整单词匹配?(y/n):\n").lower() == 'y'
# 执行搜索统计
print("\n 正在执行搜索统计...")
result = text_search_counter(file_path, search_terms, case_sensitive, whole_word)
# 显示结果
if result:
print("\n 统计结果:")
for term, count in result.items():
clean_term = re.sub(r'\\b|\\', '', term)
print(f"关键词 '{clean_term}' 出现次数:{count}次")
# 询问是否继续搜索
continue_search = input("\n是否继续搜索当前文件?(y/n):\n").lower()
if continue_search != 'y':
file_path = None
# 重置文件路径以便重新选择
except KeyboardInterrupt:
print("\n 用户中断操作")
return
except Exception as e:
print(f" 发生意外错误:{str(e)}")
continue
# 运行交互界面
if __name__ == "__main__":
print("\n 欢迎使用交互式文本搜索统计工具")
interactive_search()

1783

被折叠的 条评论
为什么被折叠?



