3. Python文本处理基础:字符串操作、正则表达式入门、中文分词基础(jieba库)
做新闻情感打分,说白了就是跟文本打交道。你拿到的每条新闻,都是一堆字符串。怎么从里面提取有用的信息?怎么把一段话拆成有意义的词?这就是今天我们要啃的硬骨头。
我个人习惯,学任何技术都先搭个框架。文本处理这条线,我把它分成三层:字符串操作是基本功,正则表达式是进阶武器,中文分词是咱们做中文NLP的独门绝技。这三层一层套一层,缺一不可。
3.1 字符串操作:最基础也最常用
Python的字符串,说白了就是一堆字符排排坐。我刚开始写爬虫那会儿,每天跟字符串打交道的时间比跟女朋友说话都多。你想想看,新闻标题、正文、发布时间,哪个不是字符串?
3.1.1 字符串的增删改查
先来点最实在的。我总结了四个最常用的操作,你记牢了,后面写代码能省一半时间。
# 字符串拼接 —— 我习惯用 f-string,简洁又直观
title = "今日股市大涨"
source = "财经网"
full_title = f"{title} —— {source}"
print(full_title) # 输出:今日股市大涨 —— 财经网
# 字符串分割 —— 处理CSV数据时经常用
news_text = "2024-01-15,财经,股市回暖"
parts = news_text.split(",")
print(parts) # 输出:['2024-01-15', '财经', '股市回暖']
# 字符串替换 —— 清洗数据时必备
dirty_text = "这是一条 包含多余空格 的新闻"
clean_text = dirty_text.replace(" ", " ")
print(clean_text) # 输出:这是一条 包含多余空格 的新闻
# 字符串查找 —— 判断关键词是否存在
content = "央行宣布降息,市场反应积极"
if "降息" in content:
print("找到关键词:降息")
join() 而不是 + 来拼接字符串。前者效率高得多,我在处理10万条新闻时对比过,速度能差好几倍。
3.1.2 字符串格式化三板斧
格式化这事儿,看着简单,坑不少。我见过太多新手在这上面翻车了。直接上对比:
| 方法 | 示例 | 适用场景 |
|---|---|---|
| % 格式化 | "新闻:%s,评分:%.2f" % (title, score) |
老代码维护 |
| str.format() | "新闻:{},评分:{:.2f}".format(title, score) |
Python 3.6之前 |
| f-string | f"新闻:{title},评分:{score:.2f}" |
现代Python首选 |
我个人强烈推荐 f-string。为什么?因为它最直观,写起来最像人话。你看上面三个例子,哪个一眼就能看懂?
3.2 正则表达式入门:从文本中精准抓取
字符串操作能解决80%的问题,但剩下的20%,就得靠正则表达式了。我记得有一次做新闻分类,需要从正文里提取所有的金额数字,比如"100万元"、"5亿美元"这种。用字符串操作?累死你。正则表达式三行搞定。
3.2.1 核心元字符
别被正则表达式吓到。说白了,它就是一套"模糊匹配"的规则。我刚开始学的时候,就记了下面这几个:
import re
# . 匹配任意字符(除了换行)
# * 匹配前一个字符0次或多次
# + 匹配前一个字符1次或多次
# \d 匹配数字
# \s 匹配空白字符
# 实战:从新闻中提取日期
text = "发布时间:2024-01-15 14:30"
pattern = r"\d{4}-\d{2}-\d{2}"
match = re.search(pattern, text)
if match:
print(f"提取到日期:{match.group()}") # 输出:2024-01-15
# 实战:提取所有金额
news = "公司融资1.2亿元,估值达到50亿美元"
amounts = re.findall(r"\d+\.?\d*[亿万千]", news)
print(amounts) # 输出:['1.2亿', '50亿']
\d{11} 来匹配11位手机号。结果发现有些新闻里把"12345678901"这种数字串也匹配上了。后来我加了前缀判断,才把准确率提上去。记住:正则匹配越精确越好,别偷懒。
3.2.2 常用正则模式速查
下面这几个模式,是我做新闻处理时最常用的。你直接复制粘贴就能用:
# 匹配邮箱
email_pattern = r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"
# 匹配URL
url_pattern = r"https?://[^\s]+"
# 匹配中文(这个在中文NLP里特别重要)
chinese_pattern = r"[\u4e00-\u9fa5]+"
# 匹配标点符号
punctuation_pattern = r"[,。!?、;:""''()【】《》]"
# 实战:清洗新闻文本,只保留中文和数字
raw_text = "新闻2024:今天股市大涨!【财经】"
clean_text = re.sub(r"[^\u4e00-\u9fa5\d]", "", raw_text)
print(clean_text) # 输出:新闻2024今天股市大涨财经
3.3 中文分词基础:让机器读懂中文
英文分词简单,按空格切就行。中文呢?"今天天气真好" —— 是"今天/天气/真好"还是"今天/天/气/真好"?这就是中文分词的难点。
做新闻情感打分,分词是第一步。你想想看,如果连"高兴"和"不高兴"都分不清,还怎么打分?
3.3.1 jieba库快速上手
jieba库,中文分词界的"瑞士军刀"。我用了好几年,稳定、高效、易用。安装就一句话:
pip install jieba
来看看它的三种分词模式:
import jieba
text = "央行宣布降息,市场反应积极"
# 精确模式 —— 最常用,适合文本分析
words_exact = jieba.lcut(text)
print("精确模式:", words_exact)
# 输出:['央行', '宣布', '降息', ',', '市场', '反应', '积极']
# 全模式 —— 把所有可能的词都列出来
words_full = jieba.lcut(text, cut_all=True)
print("全模式:", words_full)
# 输出:['央行', '宣布', '降息', '市场', '场反', '反应', '积极']
# 搜索引擎模式 —— 适合搜索引擎分词
words_search = jieba.lcut_for_search(text)
print("搜索引擎模式:", words_search)
# 输出:['央行', '宣布', '降息', ',', '市场', '反应', '积极']
🎯 我的建议: 做新闻情感分析,用精确模式就够了。全模式会产生很多无意义的词,反而增加噪音。搜索引擎模式适合做搜索索引,咱们用不上。
3.3.2 自定义词典:解决专业术语
jieba虽然好用,但有些专业术语它不认识。比如"降准"、"逆回购"这些金融术语。怎么办?加自定义词典。
我曾经做过一个金融新闻分析项目,一开始jieba把"降准"切成了"降"和"准",情感打分全乱了。后来加了自定义词典,准确率直接提升20%。
# 方法一:加载词典文件
jieba.load_userdict("finance_dict.txt")
# finance_dict.txt 内容示例:
# 降准 5 n
# 逆回购 5 n
# 量化宽松 5 n
# 方法二:动态添加
jieba.add_word("降准")
jieba.add_word("逆回购")
# 测试效果
text = "央行实施降准,并开展逆回购操作"
words = jieba.lcut(text)
print(words)
# 输出:['央行', '实施', '降准', ',', '并', '开展', '逆回购', '操作']
3.3.3 停用词过滤:去掉没用的词
分词之后,你会发现有很多"的"、"了"、"是"这种词。它们对情感分析没帮助,反而增加计算量。去掉它们,就是停用词过滤。
# 加载停用词表
stop_words = set()
with open("stop_words.txt", "r", encoding="utf-8") as f:
for line in f:
stop_words.add(line.strip())
# 过滤停用词
text = "今天股市的行情非常好,投资者都很开心"
words = jieba.lcut(text)
filtered_words = [w for w in words if w not in stop_words and len(w) > 1]
print("原始分词:", words)
print("过滤后:", filtered_words)
# 输出:['今天', '股市', '行情', '非常', '好', '投资者', '都', '很', '开心']
# 过滤后:['今天', '股市', '行情', '非常', '投资者', '开心']
3.4 实战:新闻文本预处理流水线
好了,知识点讲完了。咱们来串一下,看看一个完整的新闻文本预处理流程长什么样:
import re
import jieba
def preprocess_news(text):
"""
新闻文本预处理流水线
"""
# 第一步:去除HTML标签(如果有)
text = re.sub(r"<[^>]+>", "", text)
# 第二步:统一小写,去除多余空格
text = text.lower().strip()
# 第三步:只保留中文、数字和基本标点
text = re.sub(r"[^\u4e00-\u9fa5\d,。!?]", "", text)
# 第四步:分词
words = jieba.lcut(text)
# 第五步:过滤停用词和单字词
stop_words = {"的", "了", "是", "在", "和", "就", "都", "而", "及", "与"}
filtered_words = [w for w in words if w not in stop_words and len(w) > 1]
return filtered_words
# 测试
news = "央行宣布降息,市场反应非常积极!投资者信心大增。"
result = preprocess_news(news)
print("预处理结果:", result)
# 输出:['央行', '宣布', '降息', '市场', '反应', '非常', '积极', '投资者', '信心', '大增']
你看,一条新闻经过这么一处理,就变成了干净、有意义的词列表。后面做情感打分,直接拿这些词去匹配情感词典就行。
嗯,文本处理这块就讲这么多。记住我说的:字符串操作是基本功,正则表达式是进阶武器,中文分词是咱们的独门绝技。这三样练好了,后面做情感分析就轻松多了。