两个txt文件内容中重复词的对比 求助
您好,我有两个文件内容的比对小问题想请大家帮助,帖子内容看起来呜呜喳喳的有点多,其实很简单,希望大家看一下,万分感谢。具体而言如下:
我有两个文件A.txt和B.txt(均已在下方附件中给到):
A.txt(内容示例与格式):
{A}
{B}
{C}
{D} 格式:(一个集合一行。)
{E}
{F}
B.txt(内容示例与格式):
有两行内容分别是:
整体词:部分词 格式:(整体词和部分词 以“:”隔开,上述A.txt内的一些集合之间 构成了B.txt的内容,换句话说B.txt的内容都在A.txt内,只是排序不一样。)
{A}:G,{E}#G,{F} 格式:(“:”后面的部分词以#隔开,每个集合前面都有标示的"G,"或者“H,”或者“BM,”等总计三种标识,这三个标识不参与词汇间的比对!不参与!不参与!)
{B}:G,{E}#G,{F} 格式:(“:”后面的部分词中有很多重复的集合,如{A},{B}的部分词是一样的。)
{C}:H,{I}#BM,{J}
{F}:H,{Q}
代码内容对比要求:
把B.txt中的每一行分别与A.txt中的内容循环对比,若有匹配到,那么给予其“:"前或后的一行内容。生成一个C.txt,其有五行内容,分别是:
结果示例:
A.txt中的全部词汇 是否有整体词 整体词 是否有部分词 部分词
{A} 0 0 1 G,{E}#G,{F}
{B} 0 0 1 G,{E}#G,{F}
{C} 0 0 1 H,{I}#BM,{J}
{D} 0 0 0 0
{E} 1 {A}#{B} 0 0
{F} 1 {A}#{B} 1 H,{Q}
A.txt中的全部词汇(这一行需要严格按照原来的顺序,不想搞混)
结果是这个样子的。最后生成的C是txt或者excel表都行。其实,说白了就是把B.txt内的两行词汇分别对比A.txt的内容给,之后给予了重新编排(请对比看B.txt中的一行内容:{A}:G,{E}#G,{F}与上面的结果示例结果,一看便知)。说的可能还不够简练,不过希望您能看下,很有规律可循。
我要求的结果,有点让大家费脑子了,不过找到规律的话对大家而言一定是小case,希望您练个手,帮助搞一下,再次感谢,Wish you have a nice day....
附件:
比对完了,代码如下:
import re
from collections import OrderedDict
from openpyxl import Workbook
regex = re.compile(r'{.*?}')
class Entry:
"""自定义Entry类,用于记录比对结果"""
def __init__(self) -> None:
self.has_full_word = "0"
self.full_word = "0"
self.has_partial_word = "0"
self.partial_word = "0"
# 打开A.txt并读取其全部内容
with open("A.txt", encoding="utf-8") as f:
lines = f.readlines()
# 数据清洗,每一条数据都清理开头和结尾不必要空白部分
# 变量database既作为数据库是匹配的依据
# 也用来记录结果,避免顺序被打乱
database = OrderedDict()
for entry in lines:
database = Entry()# 比对结果用Entry对象保存
# 打开B.txt并读取其全部内容
with open("B.txt", encoding="utf-8") as f:
data_pairs = f.readlines()
# 跳过首行
data_pairs = data_pairs
# 数据清洗,把每一行都拆分为 整体词 和 部分词 两部分,结构如下
# [[整体词, 部分词], [整体词, 部分词], ...]
for idx, entry in enumerate(data_pairs):
data_pairs = entry.strip().split(":")
# 开始匹配
for full_word, partial_word in data_pairs:
# 是否有 部分词
if full_word in database:# 整体词出现在database中则其具有部分词
database.has_partial_word = "1"
database.partial_word = partial_word
# 对 部分词 这一列进行拆分并遍历,判断是否具有 整体词
for item in regex.findall(partial_word):
if item in database:# 如果 部分词 的子集合出现在database中
database.has_full_word = "1"# 标记该子集合具有 整体词
fw = database.full_word
database.full_word = "#".join((fw, full_word))# 增加整体词
# 准备将database记录的结果写入文件
wb = Workbook()
ws = wb.active
ws.append(['A.txt中的全部词汇', '是否有整体词', '整体词', '是否有部分词', '部分词'])
for k, v in database.items():
ws.append([k, v.has_full_word, v.full_word.strip('0#'),
v.has_partial_word, v.partial_word])
wb.save('C.xlsx')
其中openpyxl属于第三方库,用于操作Excel表格,需要额外安装。
如果逻辑上我还是理解有误请告知,文件附后,请注意解压。 我需要的最终结果可能有点复杂了,在此简化一下(这样就很简单了):
最终结果是两个文件C.txt和D.txt:
C.txt的内容示例:
A.txt中的全部词汇 整体词
{A} 0
{B} 0
{C} 0
{D} 0
{E} {A}#{B}
{F} {A}#{B}
D.txt的内容示例:
A.txt中的全部词汇 部分词
{A} G,{E}#G,{F}
{B} G,{E}#G,{F}
{C} H,{I}#BM,{J}
{D} 0
{E} 0
{F} H,{Q}
这样分开坐就很简单了,谢谢咯。 Amgalang 发表于 2022-8-17 09:48
我需要的最终结果可能有点复杂了,在此简化一下(这样就很简单了):
最终结果是两个文件C.txt和D.txt: ...
我看了你的描述,直接说吧,每个字我都看得懂,合在一起我就不知道你说的什么意思了。你并不是描述不够简洁,而是词不达意!在表述方面,你混淆了“行”与“列”这两个概念,比如描述B.txt的时候你说“有两行内容分别是:”,而实际上明明是两列内容,还有后文的“C.txt,其有五行内容”,这里的行也应该是列。正因如此,我看了你的描述至少两个小时还没完全理清楚你要表达的意思。
这个程序最大的挑战在于猜测你的需求而不在于编写程序。
我一开始觉得你的程序写起来有点挑战,会很有意思,直到花了差不多两个小时整理你的表述还没理解你的判定标准,我真的太菜了{:10_269:} Brick_Porter 发表于 2022-8-17 10:36
我看了你的描述,直接说吧,每个字我都看得懂,合在一起我就不知道你说的什么意思了。你并不是描述不够简 ...
好吧,不好意思哒 鱼友,给你添加的麻烦。我必须还得再严谨一些,在此真心感谢您的支持。
其实就是把B中的两列内容分别和A的内容对比,然后生成两个文件,分别写入B.txt中每一行对应内容的更多信息(更多信息就是指“:”的前后内容)。再次谢谢了。我再努力搞搞吧。 有产品经理的潜质了 Amgalang 发表于 2022-8-17 11:29
好吧,不好意思哒 鱼友,给你添加的麻烦。我必须还得再严谨一些,在此真心感谢您的支持。
其实就是把B中 ...
其实吧,我还是想挑战一下的,就是看完你的描述始终没有明白“整体词”和“部分词”的判定标准是什么,这也是整个程序的关键点,只要你说明白了我相信很多人都能写出你这个程序。
例如:对于{A}:G,{E}#G,{F}这条记录来说,按照你的格式(整体词:部分词)来说,{A}不就是整体词吗?
为什么在你的结果示例中却变成了{A}的整体词为0?
归根到底,还是因为你没有说明“整体词”与“部分词”的判定标准,是从格式上划分还是从其他角度划分?还是说我的理解是错的,另有其他判定标准? Brick_Porter 发表于 2022-8-17 12:42
其实吧,我还是想挑战一下的,就是看完你的描述始终没有明白“整体词”和“部分词”的判定标准是什么,这 ...
感谢您的坚持,这次直接说判定标准:
C.txt 生成于A.txt内容与B.txt中的部分词一列内容的对比。
A.txt中的全部词汇 整体词
{A} 0
{B} 0
{C} 0
{D} 0
{E} {A}#{B}
{F} {A}#{B}
判定标准:
Letheed 发表于 2022-8-17 11:43
有产品经理的潜质了
哈哈哈 努力努力 当一个经理看看 给你鱼不如给你渔,如果你只想要鱼的话,抱歉,我这里没有那么多
flex和bison了解一下
https://cn.bing.com/search?form=MOZLBR&pc=MOZI&q=flex%26bison
Amgalang 发表于 2022-8-17 15:46
感谢您的坚持,这次直接说判定标准:
C.txt 生成于A.txt内容与B.txt中的部分词一列内容的对比。
为什么{E}对应的是{A}#{B}呢? Brick_Porter 发表于 2022-8-17 17:11
为什么{E}对应的是{A}#{B}呢?
{E}在B.txt中的部分词一列出现了两次阿,然后各自对应{A}和{B}所以{A}#{B} 人造人 发表于 2022-8-17 15:57
给你鱼不如给你渔,如果你只想要鱼的话,抱歉,我这里没有那么多
flex和bison了解一下
https://cn.bing.c ...
谢谢咯,这是我目前阶段最后一个 问题了,我会学习的,感谢。 本帖最后由 ZhKQYu 于 2022-8-17 21:25 编辑
处理过后应该是这样吧
def read_file(filename):
with open(filename) as f:
return f.readlines()
def get_word(data, dic):
new_dic = {}
for line in data:
line = line.strip()
if dic.get(line) != None:
new_dic = "#".join(dic)
else:
new_dic = None
return new_dic
def get_value_key_dic(dic):
new_dic = {}
for k, v in dic.items():
for each in v:
elements = each.split("#")
for element in elements:
start = element.find("{")
end = element.find("}")
if new_dic.get(element) == None:
new_dic] = []
new_dic].append(k)
return new_dic
def write_file(filename, k_v, v_k, data):
with open(filename, "w") as f:
for line in data:
line = line.strip()
if k_v != None and v_k != None:
f.write("{}#**#{}#**#{}#**#{}#**#{}\n".format(line, 1, v_k, 1, k_v))
elif k_v != None and v_k == None:
f.write("{}#**#{}#**#{}#**#{}#**#{}\n".format(line, 0, 0, 1, k_v))
elif v_k != None and k_v == None:
f.write("{}#**#{}#**#{}#**#{}#**#{}\n".format(line, 1, v_k, 0, 0))
else:
f.write("{}#**#{}#**#{}#**#{}#**#{}\n".format(line, 0, 0, 0, 0))
def get_key_value_dic(data):
dic = {}
for line in data:
line = line.strip()
key, value = line.split(':', 1)
if dic.get(key) == None:
dic = []
dic.append(value)
return dic
def main():
file_a = read_file('A.txt')
file_b = read_file('B.txt')
key_value_dic = get_key_value_dic(file_b)
part_dic = get_word(file_a, key_value_dic)
value_key_dic = get_value_key_dic(key_value_dic)
all_dic = get_word(file_a, value_key_dic)
write_file("C.txt", part_dic, all_dic, file_a)
if __name__ == '__main__':
main() ZhKQYu 发表于 2022-8-17 20:46
处理过后应该是这样吧
收到了,完美解决,真的很感谢您,我好好学习代码。祝你万事如意,14#的朋友为这个问题跟我讨论了好长时间,所以最佳答案 我给他了。希望理解。再次感谢。 ZhKQYu 发表于 2022-8-17 20:46
处理过后应该是这样吧
您好,收到了,完美解决了我的问题,真的很感谢您的帮助。这次之后我也学到了要更加简练,清晰的说出自己需求的必要性,再次感谢您的帮助。祝你万事如意....
页:
[1]