查看: 697|回复: 16
打印 上一主题 下一主题

[工具] txt文本格式化工具mdxFormat(python3.9.5编写)

[复制链接]

该用户从未签到

3

主题

46

回帖

3524

积分

贡士

Rank: 6Rank: 6

积分
3524
跳转到指定楼层
1
发表于 2021-7-25 10:47:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本工具适用python3.9.5编写。可以把指定路径(包含子目录)下的txt文档格式化为mdxbuilder使用的格式(每个词条三行:key,value,</>)。
特点:
1.支持不同编码格式的txt文档,默认输入输出均为“gbk”编码。
2.我写这个工具是为了整理个人的常用资料,为关键词添加超链接,实现跳转。
ps:我以前一直使用其他人写好的程序格式化txt文档,但是如果关键字之间存在嵌套,超链接格式化有问题,所以我自己编写了这个程序,但还有一点不完美之处,就是不能很好的解决自身跳转的超链接。望大神指点!

微信截图_20210725104152.png (31.87 KB, 下载次数: 3)

这就是转换为mdx后的显示效果

这就是转换为mdx后的显示效果

mdxFormatV3_5上传.rar

2.57 KB, 下载次数: 76, 下载积分: 米 -5 粒

售价: 5 粒米  [记录]  [购买]

txt文本格式化工具mdxFormat(python3.9.5编写)

评分

1

查看全部评分

该用户从未签到

3

主题

46

回帖

3524

积分

贡士

Rank: 6Rank: 6

积分
3524
推荐
 楼主| 发表于 2021-7-26 12:34:25 | 只看该作者
n0thing 发表于 2021-7-26 02:18
能不能發一個 .txt 的範例?

txt文档的文件名为关键字、文件内容就是词典内容。

我主要为了实现资料间的超链接跳转。

范例.zip

5.57 KB, 下载次数: 26, 下载积分: 米 -5 粒

售价: 1 粒米  [记录]  [购买]

  • TA的每日心情

    2021-7-8 21:03
  • 签到天数: 81 天

    [LV.6]常住居民II

    1

    主题

    222

    回帖

    1万

    积分

    状元

    Rank: 9Rank: 9Rank: 9

    积分
    11722

    QQ 章

    推荐
    发表于 2021-7-26 02:18:24 | 只看该作者
    能不能發一個 .txt 的範例?
  • TA的每日心情
    开心
    2023-1-18 23:24
  • 签到天数: 211 天

    [LV.7]常住居民III

    427

    主题

    4539

    回帖

    9万

    积分

    超级版主

    Rank: 12Rank: 12Rank: 12

    积分
    92011

    灌水大神章小蜜蜂章笑傲江湖章翰林院专用章管理组专用章城管大队长

    2
    发表于 2021-7-25 11:58:06 | 只看该作者
    默认输入输出均为“gbk”编码
    能不能默认输出UTF-8编码呢?“gbk”编码不方便文本编辑啊
  • TA的每日心情
    开心
    2019-8-21 19:27
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    61

    主题

    627

    回帖

    16万

    积分

    状元

    Rank: 9Rank: 9Rank: 9

    积分
    162733

    QQ 章灌水大神章笑傲江湖章

    3
    发表于 2021-7-25 12:23:14 | 只看该作者
    支持mdx制作脚本

    该用户从未签到

    3

    主题

    46

    回帖

    3524

    积分

    贡士

    Rank: 6Rank: 6

    积分
    3524
    5
     楼主| 发表于 2021-7-25 14:34:00 | 只看该作者
    本帖最后由 muyuzhth0 于 2021-7-25 14:38 编辑
    kyletruman 发表于 2021-7-25 11:58
    能不能默认输出UTF-8编码呢?“gbk”编码不方便文本编辑啊


    我制作的txt文档源文件是gbk格式的,如果您的是utf-8,只需要把writeTxt()函数里,f=open(outPath,"a",encoding="ANSI")这条语句的ANSI修改为utf-8即可。

    评分

    1

    查看全部评分

    该用户从未签到

    3

    主题

    46

    回帖

    3524

    积分

    贡士

    Rank: 6Rank: 6

    积分
    3524
    6
     楼主| 发表于 2021-7-25 14:34:45 | 只看该作者
    本帖最后由 muyuzhth0 于 2021-7-25 14:40 编辑

    输出默认是gbk
  • TA的每日心情
    擦汗
    2021-11-17 09:18
  • 签到天数: 79 天

    [LV.6]常住居民II

    3

    主题

    269

    回帖

    2434

    积分

    解元

    Rank: 5Rank: 5

    积分
    2434

    QQ 章

    9
    发表于 2021-10-6 20:16:02 | 只看该作者
    我的版本是 3.9.7  , 遇到了问题 。请帮助

    1. ❯ python mdxFormat_upload_V3.5.py
    2. 没有发现文件名相同的文件,处理中...
    3. 找到了4个txt文档,
    4. 开始格式化、合并文档:
    5. 读取文档失败:/Users/vivian/Downloads/mdxFormat_upload_V3.5/test/药品检查管理办法.txt
    6. 已完成第  1   个读取文档失败:/Users/vivian/Downloads/mdxFormat_upload_V3.5/test/我的广告法管理条例.txt
    7. 已完成第  2   个读取文档失败:/Users/vivian/Downloads/mdxFormat_upload_V3.5/test/北京市反食品浪费规定.txt
    8. 已完成第  3   个读取文档失败:/Users/vivian/Downloads/mdxFormat_upload_V3.5/test/中国共产党组织工作条例.txt
    9. 已完成第  4   个
    10. 开始循环添加超链接关键词辅助标记:
    11. 已完成第  4   个
    12. 开始循环清理嵌套的冗余的超链接关键词辅助标记:
    13. 已完成第  4   个
    14. 开始添加超链接,
    15. 开始清理辅助标记,
    16. 开始写入文本,
    17. Traceback (most recent call last):
    18.   File "/Users/vivian/Downloads/mdxFormat_upload_V3.5/mdxFormat_upload_V3.5.py", line 219, in <module>
    19.     main()
    20.   File "/Users/vivian/Downloads/mdxFormat_upload_V3.5/mdxFormat_upload_V3.5.py", line 213, in main
    21.     mdxFormat(path,outputPath)
    22.   File "/Users/vivian/Downloads/mdxFormat_upload_V3.5/mdxFormat_upload_V3.5.py", line 198, in mdxFormat
    23.     if writeTxt(txt,outputPath):
    24.   File "/Users/vivian/Downloads/mdxFormat_upload_V3.5/mdxFormat_upload_V3.5.py", line 48, in writeTxt
    25.     os.mkdir(path)
    26. FileNotFoundError: [Errno 2] No such file or directory: ''
    复制代码

    该用户从未签到

    3

    主题

    46

    回帖

    3524

    积分

    贡士

    Rank: 6Rank: 6

    积分
    3524
    10
     楼主| 发表于 2021-10-6 22:34:08 | 只看该作者
    漫步云海涧 发表于 2021-10-6 20:16
    我的版本是 3.9.7  , 遇到了问题 。请帮助

    mdxFormat读取文件的路径是绝对路径。你得在mdxFormat_upload_V3.5.py-中设置下文本文件的路径。有个变量“path”

    该用户从未签到

    3

    主题

    46

    回帖

    3524

    积分

    贡士

    Rank: 6Rank: 6

    积分
    3524
    11
     楼主| 发表于 2021-10-6 22:47:27 | 只看该作者
    漫步云海涧 发表于 2021-10-6 20:16
    我的版本是 3.9.7  , 遇到了问题 。请帮助

    你把在“mdxFormat_upload_V3.5.py”中修改的代码贴出来看下。
  • TA的每日心情
    擦汗
    2021-11-17 09:18
  • 签到天数: 79 天

    [LV.6]常住居民II

    3

    主题

    269

    回帖

    2434

    积分

    解元

    Rank: 5Rank: 5

    积分
    2434

    QQ 章

    12
    发表于 2021-10-7 07:59:27 | 只看该作者
    muyuzhth0 发表于 2021-10-6 22:47
    你把在“mdxFormat_upload_V3.5.py”中修改的代码贴出来看下。

    好的!!  麻烦了

    1. import os
    2. import glob
    3. import re
    4. import time

    5. #遍历所有子文件
    6. def getFileListAll(filePath):
    7.     filelist=[]
    8.     for root, dirnames, filenames in os.walk(filePath):
    9.         for filename in filenames:
    10.             filelist.append(os.path.join(root,filename))
    11.             #print(os.path.join(root,filename))
    12.     return filelist

    13. #判断是否为txt文档
    14. def isTxts(nameList):
    15.     pattern=r"^[^~$].+\.(txt)$"   
    16.     patternObj=re.compile(pattern,re.I)
    17.     notTxtList=[]
    18.     for fileName in nameList:
    19.         if not patternObj.fullmatch(fileName):   #判断是否为txt文件   
    20.             notTxtList.append(nameList)
    21.     if notTxtList:
    22.         print("存在非txt文件:{0:},请处理后再运行程序!".format(notTxtList))
    23.         return False
    24.     else:
    25.         return True   

    26. #在指定的txt文档中查找关键字
    27. def readTxt(fileName):#strkey:查找的关键字;fileName:文件路径
    28.     pattern=r"^[^~$].+\.(txt)$"   
    29.     patternObj=re.compile(pattern,re.I)
    30.     if patternObj.fullmatch(fileName):   #判断是否为txt文件            
    31.         try:
    32.             f=open(fileName,"r",encoding="utf-8")
    33.             txt=f.read()
    34.             f.close()            
    35.         except:
    36.             print("读取文档失败:{0:}".format(fileName))
    37.             return ""            
    38.         else:   #无异常时,执行
    39.             return txt
    40.         #finally:    #无论是否异常,都执行

    41. def writeTxt(txt,outPath):
    42.     path="\".join(outPath.split("\")[0:-1])
    43.     if not os.path.exists(path):
    44.         os.mkdir(path)   
    45.     try:
    46.         f=open(outPath,"a",encoding="utf-8")
    47.         f.write(txt)
    48.         f.close()
    49.         return True            
    50.     except:
    51.         print("写入文档失败:{0:}".format(outPath))
    52.         return False
    53.         #else:   #无异常时,执行
    54.         #    return txt
    55.     #finally:    #无论是否异常,都执行

    56. def getfileName(fileList):
    57.     '''
    58.     :param fileList:文件路径列表
    59.     :return nameList:文件名称列表有扩展名
    60.     '''
    61.     nameList=[]
    62.     for fileName in fileList:
    63.         name=fileName.split("\")[-1]#提取文件名
    64.         nameList.append(name)
    65.     return nameList

    66. #显示重复的文件名,如果有重复文件显示重复的文件名称,并返回False,否则返回True
    67. def showDupFile(nameList):
    68.     '''
    69.     判断是否有文件名相同的文件
    70.     :param fileList:文件名列表,包含绝对路径
    71.     :return: 如果有重复文件显示重复的文件名称,并返回False,否则返回True
    72.     '''
    73.     if nameList:    #如果文件名列表不为空
    74.         nameSet=set(nameList)
    75.         DupNameList=[]
    76.         for item in nameSet:
    77.             if nameList.count(item)>1:
    78.                 DupNameList.append(item)
    79.         if DupNameList:#保存重复文件名的列表
    80.             for L in DupNameList:
    81.                 print("{0:}为重复的文件,请处理!".format(L))
    82.             return False
    83.         else:
    84.             print("没有发现文件名相同的文件,处理中...")
    85.             return True

    86. def nameListSort(nameList,rev=True):
    87.     '''
    88.     按照字符串长度排序
    89.     :param fileList:文件名列表
    90.     :param reverse:默认降序
    91.     :return newNameList:返回排序后的文件名新列表
    92.     '''
    93.     newNameList = sorted(nameList,key = lambda i:len(i),reverse=rev) #按照字符串长度排序,降序
    94.     return newNameList   

    95. #添加超链接
    96. def formatTxtHref(nameList,txt):
    97.     '''
    98.     func:在文本中为特定字符串添加超链接
    99.     :param hrefStr:待添加超链接的字符串
    100.     :param txt:文本字符串
    101.     :return txt:格式化的文本字符串
    102.     '''
    103.     print("\n开始循环添加超链接关键词辅助标记:")
    104.     count=0
    105.     nameListDescend=nameListSort(nameList)
    106.     for nameD in nameListDescend:
    107.         nameDSimple=nameD.replace(".txt","")
    108.         nameDSMarked="【@"+nameDSimple+"@】"
    109.         txt=txt.replace(nameDSimple,nameDSMarked)
    110.         count=count+1
    111.         print("\r已完成第{0: ^6}个".format(count),end="")     

    112.     print("\n开始循环清理嵌套的冗余的超链接关键词辅助标记:")
    113.     count=0
    114.     nameListAscend=nameListSort(nameList,rev=False)
    115.     for nameA in nameListAscend:
    116.         nameA=nameA.replace(".txt","")
    117.         pattern=r"【@([^@】]*?)【@{0:}@】".format(nameA)        
    118.         patternObjTxt=re.compile(pattern)
    119.         toHrefStr="【@"+"\\1"+"muyubug"+nameA
    120.         txt=patternObjTxt.sub(toHrefStr,txt,count=0) #替换为的字符串
    121.    
    122.         pattern=r"【@{0:}@】([^【@]*?)@】".format(nameA)        
    123.         patternObjTxt=re.compile(pattern)
    124.         toHrefStr=nameA+"\\1"+"muyubug"+"@】"
    125.         txt=patternObjTxt.sub(toHrefStr,txt,count=0) #替换为的字符串
    126.         txt=txt.replace("muyubug","")
    127.         count=count+1
    128.         print("\r已完成第{0: ^6}个".format(count),end="")
    129.    
    130.     print("\n开始添加超链接,")
    131.     pattern=r"【@([^【@]+?)@】"
    132.     patternObjTxt=re.compile(pattern)
    133.     toHrefStr=r"<a href='entry://\1'>\1</a>"
    134.     txt=patternObjTxt.sub(toHrefStr,txt,count=0) #替换为的字符串
    135.         
    136.     print("开始清理辅助标记,")
    137.     txt=txt.replace("<@>","")
    138.     return txt

    139. def formatText(fileName):
    140.     '''
    141.     func:清洗字符串,格式化
    142.     :param fileName:待处理文件
    143.     return txt:处理后的字符串
    144.     '''
    145.     #提取文件名
    146.     name=fileName.split("\")[-1].replace(".txt","")
    147.     #在文件名的每个字符键添加标记符
    148.     pattern = re.compile('.{1,1}')
    149.     matchCharList=pattern.findall(name)
    150.     nameMaked="<@>".join(matchCharList)
    151.     #生成标题部分
    152.     txtTitle=nameMaked+"\n"
    153.     #读入文件
    154.     txtContent=readTxt(fileName)            
    155.     #替换正文中的特殊字符
    156.     strList=["\n","<br>"]   
    157.     for ch in strList:
    158.         txtContent=txtContent.replace(ch,"<BR>")
    159.     #合成整个词条的内容
    160.     txt=txtTitle+txtContent+"<BR>\n</>"
    161.     return txt

    162. def mdxFormat(path,outputPath):
    163.     '''
    164.     func:格式化文本
    165.     :param path:待格式化文本的路径
    166.     :param outputPath:输出的路径和文件名
    167.     '''
    168.     fileList=getFileListAll(path)#获取指定目录下的全部文件,包括子目录中的文件
    169.     nameList=getfileName(fileList)
    170.     if isTxts(nameList):
    171.         if showDupFile(nameList):#如果没有重复文件
    172.             print("找到了{0:}个txt文档,".format(len(nameList)))

    173.             print("开始格式化、合并文档:")
    174.             count=0#txt文档数量统计
    175.             txtList=[]#存储文件内容
    176.             for fileName in fileList:               
    177.                 txt=formatText(fileName) #转换换行和<br>为<BR>                  
    178.                 txtList.append(txt)
    179.                 count+=1
    180.                 print("\r已完成第{0: ^6}个".format(count),end="")                  
    181.             txt="\n".join(txtList)
    182.             
    183.             #添加超链接
    184.             txt=formatTxtHref(nameList,txt)
    185.             print("开始写入文本,")
    186.             if writeTxt(txt,outputPath):
    187.                 print("文件合并输出成功!")
    188.             else:
    189.                 print("Error:Merge!")
    190.                 return  
    191.                
    192. def main():
    193.     timeStart = time.time()



    194.     path=r"/Users/vivian/Downloads/mdxFormat_upload_V3.5/test"
    195.    
    196.     outputPath=r"/Users/vivian/Downloads/mdxFormat_upload_V3.5/output/demo.txt"
    197.    
    198.     mdxFormat(path,outputPath)

    199.     timeEnd = time.time()
    200.     print("程序运行了%d秒"%(timeEnd-timeStart))

    201. if __name__ == '__main__':
    202.     main()
    复制代码

    该用户从未签到

    3

    主题

    46

    回帖

    3524

    积分

    贡士

    Rank: 6Rank: 6

    积分
    3524
    13
     楼主| 发表于 2021-10-7 19:54:52 | 只看该作者

    你修改了哪条?

    该用户从未签到

    3

    主题

    46

    回帖

    3524

    积分

    贡士

    Rank: 6Rank: 6

    积分
    3524
    14
     楼主| 发表于 2021-10-7 21:48:13 | 只看该作者

    path=r"/Users/vivian/Downloads/mdxFormat_upload_V3.5/test"
    outputPath=r"/Users/vivian/Downloads/mdxFormat_upload_V3.5/output/demo.txt"
    这两条有问题吧,应该是下面这个格式
    r"D:\U盘同步\百科\00txt词条汇总"
  • TA的每日心情
    擦汗
    2021-11-17 09:18
  • 签到天数: 79 天

    [LV.6]常住居民II

    3

    主题

    269

    回帖

    2434

    积分

    解元

    Rank: 5Rank: 5

    积分
    2434

    QQ 章

    15
    发表于 2021-10-8 07:10:18 | 只看该作者
    muyuzhth0 发表于 2021-10-7 21:48
    path=r"/Users/vivian/Downloads/mdxFormat_upload_V3.5/test"
    outputPath=r"/Users/vivian/Downloads/md ...

    我用的是mac电脑, path 是放的存放txt词条的目录 , outputpath 是输出的txt文件
  • TA的每日心情
    开心
    2022-1-20 19:27
  • 签到天数: 157 天

    [LV.7]常住居民III

    0

    主题

    495

    回帖

    4914

    积分

    贡士

    Rank: 6Rank: 6

    积分
    4914
    16
    发表于 2022-2-18 10:09:24 | 只看该作者
    弄个windows操作界面该多好

    该用户从未签到

    3

    主题

    46

    回帖

    3524

    积分

    贡士

    Rank: 6Rank: 6

    积分
    3524
    17
     楼主| 发表于 2022-2-18 19:10:21 | 只看该作者
    lixiaoshun 发表于 2022-2-18 10:09
    弄个windows操作界面该多好

    sorry!算法还不完善,需要的人也不多,空闲时间比较少....暂时没有写GUI的打算