kindle的笔记推荐方式是使用clippings.io网站,可以自动去重标签,简化阅读,同时按书名分类,方便导入印象笔记。
这里使用python自己尝试去重。方法是遍历每段文字时,取每段的前8个字符,加入到集合。如果所遍历的文字没有出现在集合中,就写入到txt文件中。反之,则不写入。
方法一:
rtext=open("My Clippings.txt","r",encoding='utf-8')#kindle中的txt放到py文件的根目录
wtext=open("Clipping.txt","w",encoding='utf-8')#输出的文件名
lines=set() #声明lines是空集合
for i in rtext:
a = i.strip() #去除换行键
g=a[:8]#通过每行的前8个字符来比对
if g not in lines:
lines.add(g)#集合中没有g的记录,则添加进去
wtext.write(a+"\n\n\t") #逐行写入并加入两个回车和一个首行缩进,根据自己的喜好是否阅读时有回车,不喜欢删除一个\n
kindle选择文字毕竟没有手机那么灵敏,同时kindle的高亮笔记只有选中过,就会自动添加到My Clippings.txt中,即使取消高亮或redo也会生成,而不会删除不需要的笔记。多次选中文字就会有重复的笔记生成,我的习惯是以最后一次为满意的结果。所以我将列表反着遍历,取最后一次的结果,否则正常遍历就会写入第一次出现的文字。 方法二,有个小缺陷就是书的名字出现在每本书笔记的末尾。
方法二:
rtext=open("My Clippings.txt","r",encoding='utf-8').readlines()#kindle中的txt放到py文件的根目录,逐段读取并生成列表
wtext=open("Clipping.txt","w",encoding='gb18030')#输出的文件名,编码方式要gb18030,否则乱码
lines=set() #声明lines是空集合
reverse_list=[]
rtext.reverse()
for i in rtext:
g = i[:8]#通过每行的前8个字符来比对
if g not in lines:#集合中没有g的记录,则添加进去
lines.add(g)
reverse_list.append(i)
reverse_list.reverse()#逆序列表,变成正常的顺序
for j in reverse_list:
wtext.write(j+'\n\t')#逐行写入并加入一个回车和一个缩进,根据自己的喜好是否阅读时有回车,不喜欢删除\n
在Python的re模块中,search(), findall(), 和 finditer() 方法都是用于在字符串中搜索正则表达式的匹配项,但它们之间有一些关键的区别:
re.search():
功能:在给定的字符串中搜索第一个位置,其中指定的正则表达式匹配。
返回:如果找到匹配项,则返回一个匹配对象;如果没有找到匹配项,则返回None。
用途:通常用于检测某个模式是否存在于字符串中,而不仅仅是检索所有匹配项。
re.findall():
功能:在给定的字符串中查找所有与正则表达式匹配的子串,并返回一个包含所有匹配子串的列表。
返回:一个列表,包含所有匹配的子串。
用途:当需要获取所有匹配的子串时使用,返回的是一个列表,方便进一步处理。
re.finditer():
功能:在给定的字符串中查找所有与正则表达式匹配的子串,但返回的是一个迭代器,其中的每个元素都是一个匹配对象。
返回:一个迭代器,可以迭代出所有匹配的Match对象。
用途:当需要访问每个匹配的详细信息,如起始位置、结束位置、组等,或者当处理大量匹配项时,使用迭代器可以节省内存。
b 是一个特殊的字符序列,称为单词边界(word boundary)。它代表一个位置,该位置前后的字符要么都是单词字符,要么都不是单词字符。换句话说,b 匹配的是一个单词和非单词字符的边界。
这个脚本使用了正则表达式来匹配书名和书籍内容。您可能需要根据Clippings.txt文件的实际格式调整正则表达式。
这个脚本假设每本书的批注都会紧接着书名出现,并且每本书的内容都被 == = 包围。
脚本中处理时间戳的方式非常基础,只是简单地查找并显示第一个匹配的时间戳。如果Clippings.txt文件中包含多个时间戳,可能需要调整这部分逻辑。
字典book_annotations用于按书名存储书籍的批注和时间戳。每个书籍的批注存储在一个列表中,以便能够处理多段批注。
脚本输出每本书的标题、时间戳和所有批注,每个批注之间用一行分隔符分隔。
book_annotations字典中的数据格式如下:
{‘\ufeff书名1’: {‘timestamp’: ‘Tuesday, July 2, 2019 3:13:44 PM’, ‘annotations’: [‘标注1’,‘标注2’,‘标注3’] },
‘\ufeff书名2’: {‘timestamp’: ‘Tuesday, July 2, 2020 4:13:24 PM’, ‘annotations’: [‘标注1’,‘标注2’,‘标注3’] },
‘\ufeff书名3’: {‘timestamp’: ‘Tuesday, July 2, 2021 5:13:44 PM’, ‘annotations’: [‘标注1’,‘标注2’,‘标注3’] } }
import re
def remove_duplicates(items):
# 创建一个新列表来存储结果
filtered_items = []
# 遍历列表,除了最后一个元素
for i in range(len(items) - 1):
current = items[i]
next_item = items[i + 1]
# 检查字符串的前5个字符或第5个字符之后的部分是否相同
if (len(current) >= 5 and len(next_item) >= 5 and
(current[5:] == next_item[5:] or current[:5] == next_item[:5])):
# 比较长度并选择较长的字符串
if len(current) >= len(next_item):
filtered_items.append(current)
# print(next_item)
else:
# print(current)
filtered_items.append(next_item)
else:
filtered_items.append(current)
# 添加最后一个元素到结果列表
filtered_items.append(items[-1])
# 移除重复的元素(如果有的话)
filtered_items = list(dict.fromkeys(filtered_items))
return filtered_items
# 假设clippings.txt文件位于脚本同一目录下
clippings_file = 'E:\My Clippings.txt'
# 用来存储书籍的批注
book_annotations = {}
# 正则表达式来匹配书名和时间戳(如果可用)
book_pattern = re.compile(r'(.*?)\n- Your (Note|Highlight).*?Added on (.*?)\n(.*?)==========\n', re.DOTALL)
# 读取文件
with open(clippings_file, 'r', encoding='utf-8') as file:
content = file.read()
# 匹配并处理每本书的内容
matches = book_pattern.finditer(content)
for match in matches:
# 书籍标题
book_title = match.group(1).strip()
# 批注类型
note_type = match.group(2)
# 书籍内容(包括所有批注)
note_content = match.group(4).strip()
# 假设我们只保留第一个时间戳作为代表
# 这里简单处理,没有具体实现复杂的时间戳解析
# 您可能需要根据实际情况调整这部分逻辑
timestamp_match = match.group(3).strip()
# 根据批注类型添加标记
if note_type == 'Note':
note_content = f"[Note] {note_content}"
if book_title in book_annotations:
book_annotations[book_title]['annotations'].append(note_content)
else:
book_annotations[book_title] = {'timestamp': timestamp_match, 'annotations': [note_content]}
# 输出每本书的标题、时间戳和批注
for book_title, info in book_annotations.items():
print(f"Book Title: {book_title}")
print(f"Timestamp: {info['timestamp']}")
new = remove_duplicates(info['annotations'])
for annotation in new:
print(annotation)
print("-" * 30) # 分隔符,用于区分不同的批注