TxT2Docx/test.py

438 lines
19 KiB
Python
Raw Permalink Normal View History

2025-10-07 15:46:36 +08:00
import re
import random
from typing import List, Dict, Tuple, Optional
import jieba
import jieba.posseg as pseg
class EnhancedArticleRewriter:
"""
增强版文章智能改写工具
实现更自然的句子变化符合人工书写逻辑
"""
def __init__(self):
# 标点符号定义
self.sentence_endings = ['', '', '', '']
self.pause_marks = ['', '', '', '']
# 句子长度分布(模拟人工书写习惯)
self.sentence_length_distribution = {
'short': (5, 15), # 短句
'medium': (16, 30), # 中句
'long': (31, 50), # 长句
'extra_long': (51, 80) # 超长句
}
# 连接词库(更丰富的连接词)
self.connectors = {
'sequence': ['随后', '接着', '然后', '紧接着', '继而', '进而'],
'addition': ['并且', '同时', '此外', '另外', '再者', '况且', '而且'],
'contrast': ['但是', '然而', '不过', '可是', '', '反而', '相反'],
'cause': ['因为', '由于', '因此', '所以', '故而', '从而'],
'condition': ['如果', '假如', '倘若', '若是', '要是'],
'concession': ['虽然', '尽管', '即使', '纵然', '固然'],
'summary': ['总之', '综上', '总的来说', '概括地说', '简言之'],
'example': ['比如', '例如', '譬如', '好比', '正如'],
'emphasis': ['特别是', '尤其是', '更重要的是', '值得注意的是'],
'explanation': ['也就是说', '换句话说', '具体来说', '准确地说']
}
# 句式模板
self.sentence_patterns = {
'statement': ['{}'], # 陈述句
'emphasis_front': ['值得注意的是,{}', '需要强调的是,{}', '重要的是,{}'],
'emphasis_back': ['{},这一点尤为重要', '{},这是关键所在'],
'question_rhetorical': ['难道不是{}吗?', '{},不是吗?'],
'parallel': ['不仅{},而且{}', '{},又{}', '一方面{},另一方面{}'],
'progressive': ['先是{},然后{}', '{}{}', '{}发展到{}']
}
# 同义词/近义词替换库
self.synonyms = {
'发展': ['演进', '进步', '演变', '发展', '进化', '提升', '推进'],
'改变': ['变化', '转变', '改变', '变革', '转换', '调整', '革新'],
'重要': ['关键', '重要', '核心', '主要', '根本', '要紧', '关键性'],
'影响': ['作用', '影响', '效应', '冲击', '波及', '涉及'],
'提高': ['提升', '增强', '改善', '优化', '加强', '增进'],
'显示': ['表明', '显示', '说明', '揭示', '体现', '反映', '展现'],
'通过': ['利用', '运用', '借助', '凭借', '依靠', '经由'],
'实现': ['达成', '实现', '完成', '达到', '做到', '落实'],
'问题': ['难题', '问题', '挑战', '困难', '障碍', '瓶颈'],
'方法': ['方式', '手段', '途径', '办法', '策略', '措施'],
'需要': ['需要', '要求', '必须', '应该', '亟需', '急需'],
'能够': ['能够', '可以', '', '', '得以', '足以'],
'非常': ['十分', '相当', '特别', '格外', '极其', '异常', '颇为'],
'很多': ['许多', '大量', '众多', '诸多', '不少', '大批'],
'所有': ['全部', '一切', '所有', '整个', '全体', '各个'],
'已经': ['', '已经', '业已', '早已', '都已'],
'正在': ['', '正在', '', '正处于', '目前正'],
'越来越': ['日益', '愈发', '愈加', '更加', '日渐', '渐渐'],
'不断': ['持续', '不断', '连续', '陆续', '继续', '频繁'],
'各种': ['各类', '各种', '多种', '种种', '诸般', '多样'],
}
def _get_random_sentence_length_type(self) -> str:
"""根据正态分布随机选择句子长度类型"""
# 模拟人工书写的句长分布:中句最多,短句和长句次之,超长句最少
weights = {'short': 25, 'medium': 40, 'long': 25, 'extra_long': 10}
types = list(weights.keys())
probs = [weights[t] / 100 for t in types]
return random.choices(types, weights=probs)[0]
def _smart_split_merge_sentences(self, sentences: List[str]) -> List[str]:
"""智能拆分和合并句子,创造自然的长短句节奏"""
if not sentences:
return sentences
result = []
i = 0
while i < len(sentences):
# 获取目标句长类型
target_type = self._get_random_sentence_length_type()
min_len, max_len = self.sentence_length_distribution[target_type]
current_sentence = sentences[i].strip()
current_len = len(current_sentence)
# 如果当前句子太长,尝试拆分
if current_len > max_len:
split_sentences = self._split_sentence_naturally(current_sentence, max_len)
result.extend(split_sentences)
# 如果当前句子太短,尝试与下一句合并
elif current_len < min_len and i + 1 < len(sentences):
# 30%概率合并短句
if random.random() < 0.3:
merged = self._merge_sentences(current_sentence, sentences[i + 1])
result.append(merged)
i += 1 # 跳过下一句
else:
result.append(current_sentence)
# 长度合适,直接添加
else:
result.append(current_sentence)
i += 1
return result
def _split_sentence_naturally(self, sentence: str, max_length: int) -> List[str]:
"""自然地拆分长句"""
if len(sentence) <= max_length:
return [sentence]
# 保存句尾标点
ending = ''
for mark in self.sentence_endings:
if sentence.endswith(mark):
ending = mark
sentence = sentence[:-len(mark)]
break
# 优先在逗号处拆分
parts = []
if '' in sentence:
segments = sentence.split('')
current = ""
for i, segment in enumerate(segments):
if not current:
current = segment
elif len(current + '' + segment) <= max_length:
current += '' + segment
else:
# 添加句号使其成为完整句子
if random.random() < 0.7: # 70%概率添加句号
parts.append(current + '')
else: # 30%概率使用其他句尾
parts.append(current + random.choice(['', '', '']))
current = segment
# 处理最后一部分
if current:
parts.append(current + ending)
else:
# 如果没有逗号,尝试在其他标点处拆分
parts = [sentence + ending]
return parts if parts else [sentence + ending]
def _merge_sentences(self, sent1: str, sent2: str) -> str:
"""智能合并两个句子"""
# 移除第一个句子的句尾标点
for mark in self.sentence_endings:
if sent1.endswith(mark):
sent1 = sent1[:-len(mark)]
break
# 选择连接方式
merge_type = random.choice(['comma', 'connector', 'semicolon'])
if merge_type == 'comma':
return sent1 + '' + sent2
elif merge_type == 'connector':
# 随机选择连接词类型
conn_type = random.choice(list(self.connectors.keys()))
connector = random.choice(self.connectors[conn_type])
return sent1 + '' + connector + sent2
else: # semicolon
return sent1 + '' + sent2
def _replace_synonyms(self, text: str, intensity: float) -> str:
"""同义词替换"""
words = list(jieba.cut(text))
result = []
for word in words:
if word in self.synonyms and random.random() < intensity:
# 选择一个同义词(避免选到原词)
alternatives = [w for w in self.synonyms[word] if w != word]
if alternatives:
result.append(random.choice(alternatives))
else:
result.append(word)
else:
result.append(word)
return ''.join(result)
def _adjust_sentence_structure(self, sentence: str, intensity: float) -> str:
"""调整句子结构,使其更自然"""
if random.random() > intensity:
return sentence
# 保存句尾标点
ending = ''
for mark in self.sentence_endings:
if sentence.endswith(mark):
ending = mark
sentence = sentence[:-len(mark)]
break
# 随机选择调整方式
adjust_type = random.choice(['reorder', 'add_emphasis', 'change_pattern'])
if adjust_type == 'reorder' and '' in sentence:
# 重新排列子句
parts = sentence.split('')
if len(parts) >= 2:
# 智能重排:不是完全随机,而是有逻辑的调整
if len(parts) == 2:
# 两个子句直接交换
sentence = parts[1] + '' + parts[0]
else:
# 多个子句,将中间的提前或延后
mid_idx = len(parts) // 2
if random.random() < 0.5:
# 中间提前
parts = [parts[mid_idx]] + parts[:mid_idx] + parts[mid_idx + 1:]
else:
# 中间延后
parts = parts[:mid_idx] + parts[mid_idx + 1:] + [parts[mid_idx]]
sentence = ''.join(parts)
elif adjust_type == 'add_emphasis':
# 添加强调
if random.random() < 0.3:
pattern = random.choice(self.sentence_patterns['emphasis_front'])
sentence = pattern.format(sentence)
elif random.random() < 0.3:
pattern = random.choice(self.sentence_patterns['emphasis_back'])
sentence = pattern.format(sentence)
elif adjust_type == 'change_pattern':
# 改变句式
if '' in sentence and random.random() < 0.4:
parts = sentence.split('', 1)
if len(parts) == 2:
# 使用并列或递进句式
if random.random() < 0.5:
sentence = f"不仅{parts[0]},而且{parts[1]}"
else:
sentence = f"{parts[0]},进而{parts[1]}"
return sentence + ending
def _add_natural_variations(self, sentence: str, intensity: float) -> str:
"""添加自然的语言变化"""
if random.random() > intensity:
return sentence
variations = []
# 20%概率添加过渡词
if random.random() < 0.2:
transition = random.choice(['其实', '事实上', '实际上', '确实', '显然'])
variations.append(f"{transition}{sentence}")
# 15%概率添加程度副词
if random.random() < 0.15:
adverb = random.choice(['', '更加', '尤其', '特别', '格外'])
# 简单地在"是"、"有"、"能"等词前添加副词
for verb in ['', '', '', '', '']:
if verb in sentence:
sentence = sentence.replace(verb, f"{adverb}{verb}", 1)
break
return variations[0] if variations else sentence
def rewrite(self, text: str, config: Dict = None) -> str:
"""
主函数改写文章
参数:
text: 输入文章
config: 配置字典
- intensity: 修改强度 0.0-1.0
- preserve_meaning: 是否保持原意
- natural_flow: 是否保持自然流畅
- vary_sentence_length: 是否变化句长
"""
if config is None:
config = {}
# 设置默认值
config.setdefault('intensity', 0.6)
config.setdefault('preserve_meaning', True)
config.setdefault('natural_flow', True)
config.setdefault('vary_sentence_length', True)
intensity = config['intensity']
# 分段处理
paragraphs = [p.strip() for p in text.split('\n') if p.strip()]
result_paragraphs = []
for para in paragraphs:
# 分句
sentences = self._split_sentences(para)
# 1. 首先进行句子长短调整
if config['vary_sentence_length']:
sentences = self._smart_split_merge_sentences(sentences)
# 2. 处理每个句子
processed_sentences = []
for i, sent in enumerate(sentences):
# 同义词替换
sent = self._replace_synonyms(sent, intensity * 0.5)
# 句子结构调整
sent = self._adjust_sentence_structure(sent, intensity * 0.7)
# 添加自然变化
sent = self._add_natural_variations(sent, intensity * 0.3)
processed_sentences.append(sent)
# 3. 段落重组(偶尔调整句子顺序)
if len(processed_sentences) > 3 and random.random() < intensity * 0.2:
# 20%概率微调句子顺序(只交换相邻句子)
idx = random.randint(0, len(processed_sentences) - 2)
processed_sentences[idx], processed_sentences[idx + 1] = \
processed_sentences[idx + 1], processed_sentences[idx]
result_paragraphs.append(''.join(processed_sentences))
return '\n\n'.join(result_paragraphs)
def _split_sentences(self, text: str) -> List[str]:
"""改进的句子分割"""
# 处理多种句尾标点
pattern = '([。!?…]+)'
parts = re.split(pattern, text)
sentences = []
for i in range(0, len(parts) - 1, 2):
if parts[i].strip():
sentences.append(parts[i] + parts[i + 1])
# 处理最后一个部分
if len(parts) % 2 == 1 and parts[-1].strip():
sentences.append(parts[-1] + '') # 添加默认句号
return sentences
def demo():
"""使用示例"""
sample_text = """
最近晓蕾又上热搜了
咋回事呢原来她和老公刘剑一起开了直播带货的副业但特意声明她早就离开了上海电视台的编制也不拿电视台的工资换句话说现在卖东西完全是私营业态
这事儿一下子引爆了大家的八卦魂毕竟明星主持扎堆直播间也不算新鲜事但还是挺多人纳闷这些当年的 "话筒头牌"是不是集体选择摆烂了
其实晓蕾和刘剑干脆落落大方在直播间直接回应了这点俩人意思很明确我们不是来拉低职业口碑的而且还耐心解释了自己转行的理由
曾经的大佬变成了烟火气
说到晓蕾不了解点她背景都不好意思讨论人家当年上视新闻部的 "当家花旦"光学历和气质足够秒杀隔壁主持圈的八条街而刘剑早年可是 "台柱子"播音腔精致到令人耳膜怀孕照理来说这样一对在编制铁饭碗里躺平一辈子没毛病
可人家偏不
晓蕾说过这样一句话其实我就是个普通人 真的那么普通吗她不这么说没人敢忘了她的标杆履历啊她离开台里后居然一头扎进了童语言教育这个赛道一干就是十年让机构做到了业内小圈子的爆款水准
而这次直播打的商品也不混乱主打性价比和实用属性晓蕾每件商品还得亲测过如果你觉得她自吹自擂建议去看看她直播间的粉丝评论大家的意思是晓蕾推品 = ·9放心买
刘剑这枚 前一哥更狠
说晓蕾牛别忘了刘剑十年前也上演了一场 豪赌那个年代辞去电视台稳定工作 打水漂 差不多
可是刘剑敢把梭全下为啥因为他看中了播音考生和辅导课程的市场那时还没有多少人扎堆干这块他觉得这是个机会
果然就这么辞了职工作的腰板从跟组织吃工资摇身变成了名副其实的事业单位 自己家老板虽然后来也是磕磕绊绊但终究从试验田里掘出了一片肥沃地
主持人的 下海是换方向走
有人觉得曾经的新闻人主持人 跑去带货肯定是混不下去了你要放在十年前这种联想不稀奇可现在不一样了大环境变了传统媒体是真的在互联网时代被打败得找不到调
原来电视频道的观众现在早转移到手机端看知乎刷短视频甚至晚上蹲个带货直播会你说新闻节目的高冷主播现在换脸做带货主持是不是 落魄未必
晓蕾夫妻这一波实际上是转型很成功的范例不管带啥网红货他们俩把品质第一的逻辑摆明白了这样的主播不止卖产品更卖信誉靠着时间积攒了观众的信任
直播间哪门子 LOW明明是主战场
网友说得有趣谁嫌直播带货 LOW谁就输定了 道理没跑儿移动互联网成了咱生活重心生意也跟着迁移这是明显趋势看不懂的还真不想赚钱了
而且做直播一点不轻松站几个小时口播随时照顾弹幕情绪这比坐着念提词器辛苦多了像晓蕾和刘剑这样的 摸鱼资历能转过身来赚饭钱这不是
别说传统意义的职业崇拜消失殆尽你觉得稳如狗的岗位说散架就散老一辈金饭碗情结对于下一代新创别说香而是种被淘汰跑赢速度内心创新积极点
我不是电视台员工了早就离职 10 年了
"""
rewriter = EnhancedArticleRewriter()
print("=" * 60)
print("原文:")
print("=" * 60)
print(sample_text)
# 测试不同强度的改写
for intensity in [0.3, 0.6, 0.9]:
print(f"\n{'=' * 60}")
print(f"改写强度: {intensity}")
print("=" * 60)
config = {
'intensity': intensity,
'preserve_meaning': True,
'natural_flow': True,
'vary_sentence_length': True
}
result = rewriter.rewrite(sample_text, config)
print(result)
# 统计句子长度分布
sentences = re.split('[。!?…]+', result)
lengths = [len(s) for s in sentences if s.strip()]
if lengths:
print(f"\n句子长度分布: 最短={min(lengths)}, 最长={max(lengths)}, 平均={sum(lengths) / len(lengths):.1f}")
print(f"句子数量: {len(lengths)}")
if __name__ == '__main__':
# 注意需要安装jieba库
# pip install jieba
demo()