【端午安康SXY】Python正则表达式进阶用法(以批量修改Markdown英文字体为例)
文章目录
- 序言
- 1 问题缘起
- 2 Python正则表达式中的捕获元
- 2.1 re.findall与re.sub方法中使用捕获元
- 2.2 re.split方法中的捕获元用法
- 3 实战:批量修改Markdown英文字体脚本实现
- 后记
序言
本文没有序言,但是或许会有后记。
1 问题缘起
不知道写Markdown的朋友会不会觉得编辑器默认的字体不太顺眼,比如常用的Typora编辑器,以及用于博客发布的CSDN的Markdown编辑器,这两个编辑器使用的主题都是GitHub风格主题,默认字体为Arial。倒不是说Arial字体丑,但是跟其他字体比较,比如字体Times New Roman看起来就要正式很多,再不济给Arial加个斜体(Arial)也要好看很多,当然给Times New Roman再加个斜体(Times New Roman)那将绝杀(最美字体不接受反驳)。
所以以前笔者写Markdown的时候,都要手动给英文部分修改字体(要么加粗加斜,要么用<font face=times new roman>...</font>
的标签对套在英文语句上)。
这时候肯定有人要跳出来说,CY你又水博客了,你要是觉得字体丑,自己去改Typora的层叠样式表(CSS)配置文件不就完事。笔者不反对这种观点,的确找到Typora安装根目录下的resources\app\style\themes\github.css
配置文件,修改其中的默认字体(比如将Times New Roman添加到配置文件的body中即可,网上也有很多人教你怎么修改Typora的默认字体),但这里有两个难以解决的问题:
- CSDN的Markdown编辑器是无法修改默认字体的,必须依赖
<font>
标签来自定义字体; - 对笔者来说,我只想修改和英文相关的内容(注意并不一定都是英文字母,包括英文内容中可能出现的数字、标点符号、特殊符号,比如邮箱地址中就会出现各种特殊符号)的字体,因为默认的中文字体笔者觉得是可以接受的。因此改动配置文件就没那么容易了,网上也有关于如何在CSS文件中为中英文配置不同字体的方法,但是这就需要大改配置文件,并非简单地添加几个字段那么容易,而且如何判断标点符号、特殊符号也是一个难题。
不过有一个好消息,Time New Roman不识别中文,因此只要给Markdown中每一行的句首句尾添加<font face=times new roman>
和</font>
即可简单实现,这至少比一个个的给英文修改字体要简便得多,所以笔者很早之前就写过一个给Markdown配置字体的Python脚本:
# -*- coding: utf-8 -*-
# @author: caoyang
# @email: caoyang@163.sufe.edu.cn# 为Markdown每一行首尾加一个字体标签的工具函数
# 跳过标题行, 多行公式, 多行代码, 表格区域
# 跳过每行开头的无序列表标签('- '), 有序列表标签('1. ', '2. ', '3. '), 引用部分('> ')
# 默认添加的字体模式为<font face=times new roman>...</font>
def add_font_for_each_line(import_path, export_path, font_prefix='<font face=times new roman>', font_suffix='</font>'):with open(import_path, 'r', encoding='utf8') as f:lines = f.read().splitlines()export_lines = [] # 存储修改后的每一行markdown代码is_formula = False # 判断是否处于公式范围内is_code = False # 判断是否处于代码范围内for line in lines:if line.lstrip():# 引用if line.lstrip()[0] == '>':suffix = ' ' * (len(line) - len(line.lstrip())) + '>'line = line.lstrip()[1: ]# 有序列表elif line.lstrip()[: 3] in ['1. ', '2. ', '3. ', '4. ', '5. ', '6. ', '7. ', '8. ', '9. ']:suffix = ' ' * (len(line) - len(line.lstrip())) + line.lstrip()[:3]line = line.lstrip()[3: ]else:suffix = ''line = line# 多行公式if line.lstrip().startswith('$$') and is_formula:is_formula = Falseexport_lines.append(suffix + line)elif line.lstrip().startswith('$$') and (not is_formula):is_formula = Trueexport_lines.append(suffix + line)elif is_formula:export_lines.append(suffix + line)# 多行代码elif line.lstrip().startswith('```') and is_code:is_code = Falseexport_lines.append(suffix + line)elif line.lstrip().startswith('```') and (not is_code):is_code = Trueexport_lines.append(suffix + line)elif is_code:export_lines.append(suffix + line)# 空行elif len(line.strip()) == 0:export_lines.append(suffix + line)elif line.strip() == '----' or line[0] == '#' or line.strip() == '[toc]' or line.lstrip()[0] == '|':# 持续更新: 目前考虑分割线, 标题, 目录, 表格export_lines.append(suffix + line)else:# 无序列表index = line.find('- ')if index > -1:export_lines.append(suffix + line[: index + 2] + font_prefix + line[index + 2: ] + font_suffix)else:export_lines.append(suffix + ' ' * (len(line) - len(line.lstrip())) + font_prefix + line.lstrip() + font_suffix)else:export_lines.append(line) with open(export_path, 'w', encoding='utf8') as f:f.write('\n'.join(export_lines))if __name__ == '__main__':add_font_for_each_line(import_path=r'input.md',export_path=r'output.md',font_prefix='<font face=times new roman>',font_suffix='</font>')
注意上面的代码中已经充分考虑到要跳过Markdown中的多行公式、多行代码块、表格区域,以及每行开头可能出现的无序列表标签、有序列表标签、引用标签。
下面展示一个demo用于说明上述脚本的用途:
测试Markdown脚本(写入到
input.md
文件中,注意里面反引号前面的反斜杠请删除,笔者不加反斜杠的话Markdown语法容易错误识别代码区域):> 测试引用(cite): > > - 测试引用1 > - 测试引用2测试正文(Body):1. 测试有序列表(Formula):$a^{p-1}\equiv 1(\text{mod }p)$$$x^n+y^n=z^n\quad x\in\Z^*,y\in\Z^*,z\in\Z*$$2. 测试无序列表(Code):`Inline code demo`\`\`\`pythonprint('Hello world!')\`\`\`任何问题可以联系我的邮箱caoyang@163.sufe.edu.cn,Thanks!
运行上述代码,可以从
output.md
中得到如下输出:> <font face=times new roman>测试引用(cite):</font> > > - <font face=times new roman>测试引用1</font> > - <font face=times new roman>测试引用2</font><font face=times new roman>测试正文(Body):</font>1. <font face=times new roman>测试有序列表(Formula):$a^{p-1}\equiv 1(\text{mod }p)$</font>$$x^n+y^n=z^n\quad x\in\Z^*,y\in\Z^*,z\in\Z*$$2. <font face=times new roman>测试无序列表(Code):`Inline code demo`</font>\`\`\`pythonprint('Hello world!')\`\`\`<font face=times new roman>任何问题可以联系我的邮箱caoyang@163.sufe.edu.cn,Thanks!</font>
修改前后的样式对比:
非常完美,似乎我们已经得到一个很鲁棒的字体修改脚本,但是如果只是到此为止,笔者也不会浪费时间特意水一篇博客,仔细观察上面修改前后的样式对比的图片以及修改前后的Markdown脚本,仍然存在两个问题:
Times New Roman只是恰好无法识别中文,因此只需要在句首句末添加
<font face=times new roman>
和</font>
即可实现英文字体修改,那么如果是其他能够识别中文的字体就会连着中文字体一起改动,这是笔者所不期望的。有没有发现改动成Times New Roman后的英文字号相对于中文字号有点偏小?事实上
<font>
标签中还有一个size
属性,默认值是size=3
,如果改为size=4
则Times New Roman字体的英文字号与size=3
的中文字号较为相配。倘若将前缀改为
<font face=times new roman size=4>
是不可行的,因为这样会使得中文字号也会变为size=4
,相对大小不会产生变化。(原谅笔者的强迫症)
因此最好的修改脚本是能够确切地匹配到需要修改的英文内容部分,然后添加字体标签,这样才是笔者所期望的。
口说无凭,本问第三部分的新脚本将会改动得到如下的结果(字体发生改动的部分用红色标注):
> 测试引用(<font face=times new roman size=4 color=red><i>cite</i></font>):
>
> - 测试引用1
> - 测试引用2测试正文(<font face=times new roman size=4 color=red><i>Body</i></font>):1. 测试有序列表(<font face=times new roman size=4 color=red><i>Formula</i></font>):$a^{p-1}\equiv 1(\text{mod }p)$$$x^n+y^n=z^n\quad x\in\Z^*,y\in\Z^*,z\in\Z*$$2. 测试无序列表(<font face=times new roman size=4 color=red><i>Code</i></font>):`Inline code demo`\`\`\`pythonprint('Hello world!')\`\`\`任何问题可以联系我的邮箱<font face=times new roman size=4 color=red><i>caoyang@163.sufe.edu.cn</i></font>,<font face=times new roman size=4 color=red><i>Thanks</i></font>!
到这里肯定又有人要跳出来说,CY你还在水博客,这不是写几个循环和条件句就能解决的问题么?
说得好!笔者本来也是这么想的,一方面应当注意到行内可能会出现行内公式$...$
、行内代码块,HTML标签(比如<font>
)、超链接和图片([链接名](链接地址)
和![图片名](图片链接)
),这些都是无需修改字体(严格说就不能套上字体标签);另一方面,循环是下策,逐字符修改效率低下,代码写起来注定也非常冗长(要判断当前字符是否属于行内公式、行内代码、HTML标签,超链接或图片)。因此笔者试图借助正则表达式的捕获元来解决这个问题,这样要高效得多,只需要在上面的Python字体修改代码中做少量调整即可(具体阅读本文第三部分)。
2 Python正则表达式中的捕获元
在解决第一部分提出的问题前,笔者首先铺垫一下所需要的知识(最好对正则有一定了解)。
2.1 re.findall与re.sub方法中使用捕获元
常规的正则表达式是为了匹配与正则相恰的字符串,比如使用正则<[^>]+>
可以匹配HTML中的所有节点标签(如<html>
,<header>
等),然后讲匹配得到的结果替换为空字符串(即删除节点标签)即可得到HTML的纯文本信息:
# -*- coding: utf-8 -*-
# @author: caoyang
# @email: caoyang@163.sufe.edu.cnimport reregex_compiler = re.compile(r'<[^>]+>')
string = """<html><header></header><body><h1>demo</h1></body></html>"""
print(regex_compiler.findall(string))
print(regex_compiler.sub('', string))# 输出结果
"""
['<html>', '<header>', '</header>', '<body>', '<h1>', '</h1>', '</body>', '</html>']
demo
"""
可是有时候我们可能会有更特殊的需求:
- 我只想获得匹配结果的一部分字符串,如匹配HTML中的所有节点标签的名称(即
html
,header
等)? - 我只想替换匹配结果的一部分字符串,如匹配HTML中的所有节点标签,并将标签的
<
与>
替换为{
与}
(如<html>
替换为{html}
)?
这时候就需要引入捕获元的概念,具体而言,使用左右圆括号在正则表达式中框出你想要匹配得到的那部分(称之为捕获),如在上面的例子中,如果我们只想匹配HTML中的所有节点标签的名称,那么这相当于是在正则<[^>]+>
中获取[^>]+
这一部分,那么可以改为<([^>]+)>
即可实现上面的效果:
# -*- coding: utf-8 -*-
# @author: caoyang
# @email: caoyang@163.sufe.edu.cnimport reregex_compiler = re.compile(r'<[(^>]+)>')
string = """<html><header></header><body><h1>demo</h1></body></html>"""
print(regex_compiler.findall(string))
print(regex_compiler.sub(r'{\1}', string))# 输出结果
"""
['html', 'header', '/header', 'body', 'h1', '/h1', '/body', '/html']
{html}{header}{/header}{body}{h1}demo{/h1}{/body}{/html}
"""
regex_compiler.sub
中我们用\1
来匹配正则中的第一个捕获元,同理如果正则中存在多个捕获元,可以依次使用\1
,\2
,\3
进行匹配。但是这个与通常的正则编译器对捕获元替换的处理是有区别的!至少笔者的经验中更多使用的应该是$1
,$2
,$3
,但是在Python的re库中如果使用$1
,$2
,$3
来匹配捕获元是完全不起作用,大坑。(有可能是re库的版本太低,笔者使用的是2.2.1
)
2.2 re.split方法中的捕获元用法
re.split
方法可以将字符串中所有与正则匹配的部分删除,将剩下零碎的字符串以列表形式返回:
# -*- coding: utf-8 -*-
# @author: caoyang
# @email: caoyang@163.sufe.edu.cnimport reprint(re.__version__)regex_compiler_1 = re.compile(r'<[^>]+>') # 不带捕获元的正则
regex_compiler_2 = re.compile(r'<([^>]+)>') # 带捕获元的正则
string = """<html><header></header><body><h1>demo</h1><h2>demo</h2></body></html>"""
print(regex_compiler_1.split(string))
print(regex_compiler_2.split(string))# 输出结果
"""
['', '', '', '', '', 'demo', '', '', '']
['', 'html', '', 'header', '', '/header', '', 'body', '', 'h1', 'demo', '/h1', '', '/body', '', '/html', '']
"""
注意到,对于不带捕获元的正则来说,re.split
与re.findall
返回的结果是刚好互补的,具体而言,re.split
返回的列表长度总是比re.findall
列表长度多1,且将re.findall
的列表元素依次插入到re.split
元素的间隙中,即可得到原字符串。
如在前面的例子中:
regex_compiler.findall(string)
返回结果为['<html>', '<header>', '</header>', '<body>', '<h1>', '</h1>', '</body>', '</html>']
,长度为8;regex_compiler_2.findall(string)
返回结果为['', '', '', '', '', 'demo', '', '', '']
,长度为9;- 两者交叉拼接后可得原字符串:
"""<html><header></header><body><h1>demo</h1></body></html>"""
这是一个很有用的性质,这意味着你总是可以通过split方法过滤掉原字符串中不想处理的部分,对剩下的部分处理完后,再通过findall方法将字符串还原。
特别地,对于包含捕获元的正则,re.split
方法会保留捕获元中匹配得到的部分(暂时没什么用)。
3 实战:批量修改Markdown英文字体脚本实现
那么有了第二部分的铺垫,聪明的你一定已经想到如何精确匹配Markdown中的英文内容并批量修改字体了。
具体实现如下:
# -*- coding: utf-8 -*-
# @author: caoyang
# @email: caoyang@163.sufe.edu.cnimport re# 这种是针对英文字符, 包括一些特殊符号, 转为特定字体的方法
# 几乎完全照搬add_font_for_each_line函数
def add_font_for_english_words(import_path, export_path, font_prefix='<font face=times new roman size=4 color=red><i>', font_suffix='</i></font>'):with open(import_path, 'r', encoding='utf8') as f:lines = f.read().splitlines()export_lines = [] # 存储修改后的每一行markdown代码is_formula = False # 判断是否处于公式范围内is_code = False # 判断是否处于代码范围内regex_compiler_1 = re.compile(r'([a-zA-Z][a-zA-Z\+\@\-\/_=!#%\(\)\d\.:,;]*)') # 匹配英文内容regex_1 = '`[^`]+`' # 匹配行内代码regex_2 = '<[^>]+>' # 匹配HTML标签regex_3 = '\$[^\$]+\$' # 匹配行内公式regex_4 = '\[[^\]]+\]\([^\)]+\)' # 匹配超链接和图片regex_compiler_2 = re.compile(r'{}|{}|{}|{}'.format(regex_1, regex_2, regex_3, regex_4)) # 匹配行内公式, 行内代码, HTML标签, 超链接或图片链接def _add_font_for_line_by_regex(_line):_rest_list = regex_compiler_2.split(_line) # 去除掉行内公式, 行内代码, HTML标签, 超链接或图片链接剩下的字符串列表 _mask_list = regex_compiler_2.findall(_line) # 匹配到的内公式, 行内代码, HTML标签, 超链接或图片链接剩下的字符串列表assert len(_rest_list) - len(_mask_list) == 1_rest_list = list(map(lambda _x: regex_compiler_1.sub(font_prefix + r'\1' + font_suffix, _x), _rest_list))_result = _rest_list[0]for i in range(len(_mask_list)):_result += _mask_list[i]_result += _rest_list[i + 1]return _resultfor line in lines:if line.lstrip():if line.lstrip()[0] == '>':suffix = ' ' * (len(line) - len(line.lstrip())) + '>'line = line.lstrip()[1: ]elif line.lstrip()[: 3] in ['1. ', '2. ', '3. ', '4. ', '5. ', '6. ', '7. ', '8. ', '9. ']:suffix = ' ' * (len(line) - len(line.lstrip())) + line.lstrip()[:3]line = line.lstrip()[3: ]else:suffix = ''line = line# 公式三联动if '$$' in line and is_formula:is_formula = Falseexport_lines.append(suffix + line)elif '$$' in line and (not is_formula):is_formula = Trueexport_lines.append(suffix + line)elif is_formula:export_lines.append(suffix + line)# 代码三联动elif '```' in line and is_code:is_code = Falseexport_lines.append(suffix + line)elif '```' in line and (not is_code):is_code = Trueexport_lines.append(suffix + line)elif is_code:export_lines.append(suffix + line)# 空行elif len(line.strip()) == 0:export_lines.append(suffix + line)# 持续更新: 目前考虑分割线, 目录, 表格, 标题elif line.strip() == '----' or line.strip() == '[toc]' or line.lstrip()[0] == '|' or line.lstrip()[0] == '#':export_lines.append(suffix + line)else:index = line.find('- ')if index > -1:# 没有列表符# export_lines.append(suffix + line[: index + 2] + font_prefix + line[index + 2: ] + font_suffix)export_lines.append(suffix + line[: index + 2] + _add_font_for_line_by_regex(line[index + 2: ]))else:# export_lines.append(suffix + ' ' * (len(line) - len(line.lstrip())) + font_prefix + line.lstrip() + font_suffix)export_lines.append(suffix + ' ' * (len(line) - len(line.lstrip())) + _add_font_for_line_by_regex(line.lstrip()))else:export_lines.append(line) with open(export_path, 'w', encoding='utf8') as f:f.write('\n'.join(export_lines))if __name__ == '__main__':add_font_for_english_words(import_path=r'input.md',export_path=r'output.md',font_prefix='<font face=times new roman size=4><i>',font_suffix='</i></font>')
上面的代码与第一部分中的add_font_for_each_line
几乎完全相同,仅仅是修改了最后一个条件分支中的处理,即自定义了子函数_add_font_for_line_by_regex
,其中共使用两个正则:
regex_compiler_1 = re.compile(r'([a-zA-Z][a-zA-Z\+\@\-\/_=!#%\(\)\d\.:,;]*)')
这个正则即匹配英文内容,要求以字母开头(
[a-zA-Z]
),后面可以接任意数量的字母数字,或者+
,@
,-
,/
,_
,=
,!
,#
,%
,(
,)
,.
,:
,,
,;
(可以继续添加,目前只想到这么多)的特殊字符。注意整体的正则用左右圆括号框起,所以整体都是一个捕获元,因为在替换的时候是要在英文内容的左右添加字体标签,因此必须完全保留匹配到的结果,具体可见在子函数中使用了
regex_compiler_1.sub(font_prefix + r'\1' + font_suffix, _x)
;regex_compiler_2 = re.compile(r'{}|{}|{}|{}'.format(regex_1, regex_2, regex_3, regex_4))
:这个是为了匹配行内公式,行内代码、HTML标签、超链接和图片链接(
regex_1
,regex_2
,regex_3
,regex_4
正是对应这四种字符串,用或运算将它们连接起来即可达到全部匹配的效果)。由于这些内容都是不可以被添加字体标签的,就需要使用到了第二部分
re.split
中的结论,即先用regex_compiler_2.split
过滤掉行内公式,行内代码、HTML标签、超链接和图片链接,然后对剩下的部分进行regex_complier_1.sub
,再拼接被过滤掉的部分即可。
经测试,上面的脚本只是几乎能够处理所有Markdown脚本中的英文内容字体修改而不发生Markdown语法错误,但并不意味着能做到百分之百的正确,比如行内公式也可以用成对的两个$
包裹(这只考虑成对的一个$
),行内代码也可以用成对的三个反引号包裹(这里只考虑成对的一个反引号)。此外上面的脚本只能匹配以英文字母开头的英文内容,若是以数字或特殊符号开头也无法匹配,表格内的英文内容也会被自动过滤。
有兴趣的朋友可以想想是否有更好的做法,比如直接从CSS配置文件下手。
看到这里是否发现本文所有的英文内容都已经被修改了字体呢?
后记
这几天心情不错,每天都能写些东西,老板也懒得管我,想做事就做事,想写博客就写博客,想跑步就跑步(虽然又拉胯了很多,但是早晚会练回来的),相对于60天的有期徒刑,算是难得舒畅了一段时间。
人生总是如此,有低谷也有高岗,如果没有舍弃一切的勇气,那就应该坦然去面对所发生的一切。对我来说跑步状态跟我的精神状态是密切关联的。今年从寒假开始就陷入很长时间的低谷(因为被阻挠跑步很长时间),开学后重新训练,学习状态也慢慢恢复,三月底再次达到42分钟整跑完场地万米的水平(其实还是要比巅峰要差一些,去年十二月跑出三个历史最佳,队内测试场地5000米19分59秒、场地万米自测41分25秒、半马自测1小时32分41秒),然后晴天霹雳般地从四月初被关了整整60天,身体状态跌落到极点,无奈仓皇逃回老家。
突然又想说一个两年半前认识的朋友SXY,认识不久就因为我的过失产生矛盾不欢而散。一年前,因为遭遇类似经历的原因又联系过一阵子,后来又断了很久。两个月前突然又在断断续续地联系,大约是因为一起在坐牢的缘故。
说起来也可笑,自从两年半前不欢而散后,大约就再没有面对面打过招呼。其实交集很小,每次也不会聊得很久,但是总会有些许慰藉。
不知是否是为了履行那封邮件里的话。或许很快就会彻底失去联系,或许就这样平淡地持续很久,本无所谓。既要学会珍惜,也要学会看淡,人就是在这么矛盾的路上渐行渐远。
端午安康。Anyway, I wish you the best, SXY.
【端午安康SXY】Python正则表达式进阶用法(以批量修改Markdown英文字体为例)相关推荐
- 【Python】一文读懂Python正则表达式常用用法
点击上方"AI遇见机器学习",选择"星标"公众号 重磅干货,第一时间送达 编辑:爱学AI 来源:geekvi 链接: www.segmentfault.co ...
- python正则表达式group用法_Python 正则表达式中的group参数使用
Python正则表达式re模块中有个group参数,刚开始看的时候没理解,自己摸索了一下,终于知道是啥意思了,记录一下. 先看一下教程中对这个参数的说明: 老实讲,看了这个描述我也没懂是啥意思,于是在 ...
- Python使用三种方法批量修改记事本文件编码格式
应用背景:近期计划写一个贝叶斯算法邮件分类的教学案例,苦于没有足够的训练集,就让同学们帮忙每人从自己的邮箱中找几封垃圾邮件把内容复制下来放到记事本文件中发给我,但是忘了提前统一编码格式要求,所以收到的 ...
- python设置文件编码_python批量修改文件编码格式的方法
本文实例为大家分享了python批量修改文件编码格式的具体代码,供大家参考,具体内容如下 使用说明: 1.使用工具:Python2.7.6+chardet2.3.0,chardet2.3.0下载地址: ...
- Python笔记4 实例之批量修改文件名
一个简单的实现批量修改文件名的例子,以司徒TX的代码为蓝本. http://www.cnblogs.com/rubylouvre/archive/2011/07/26/2117239.html uli ...
- python改文件名_python实现批量修改文件名代码
我曾以为,写脚本是很难的,直到我遇到了Python 前言随着国内版权意识的跟进,很多影视音乐资源开始收费,而且度盘又经常随意封杀各种资源,所以,为了保护资源,老司机们越来越倾向于把资源下载到本地,但随 ...
- python正则表达式group用法_【Python】正则表达式用法
导读:正则在各语言中的使用是有差异的,本文以 Python 3 为基础.本文主要讲述的是正则的语法,对于 re 模块不做过多描述,只会对一些特殊地方做提示. 很多人觉得正则很难,在我看来,这些人一定是 ...
- python正则表达式元字符用法_正则表达式-常用元字符的基本使用
常用元字符有:[] ^ $ \ * + ? {} . python中使用正则表达式需要导入re模块 下面介绍用法 [] 指定一个字符集,[ABC]表示ABC的字符集,[^ABC] 取反, ...
- Python正则表达式 re 用法
re模块:匹配开头/结尾(^/$) https://blog.csdn.net/chenmozhe22/article/details/80602000 re模块的基础用法 https://blog. ...
- python文件命名 数字_python 批量修改数字类的文件名
今天碰到一个小问题,下载音频的时候,文件名的名字变成了数字,排序呢,是按照数字的大小往下排的. 想自己给它们重新起名字,但是又不打乱音频的顺序.好吧,那就自己写写代码吧. 思路就是遍历音频文件的数字文 ...
最新文章
- vivo统一告警平台建设与实践
- Asp.Net中跳转页面有那几种方法
- 编译GSLSDevil的全过程
- synchronized同步方法
- Redis分布式锁问题
- anaconda哪个版本是 python3.6_windows10(64位)Anaconda3+Python3.6搭建Tensorflow(cpu版本)及keras...
- php赋值就变错误了,PHP基础陷阱题(变量赋值)_PHP教程
- 单片机ADC采样算法----卡尔曼滤波
- php字符串转openssl格式,将OpenSSL生成的RSA公钥转换为OpenSSH格式(PHP)
- Minitab控制图Xbar-R中认为数据异常的八项检验(8个异常趋势图)
- 25个常用的正则表达式汇总
- 记录进行Uniprot转化为Entrez ID的过程
- #今日论文推荐# 中国矿大团队,开发集成多尺度深度学习模型,用于 RNA 甲基化位点预测
- 全排列【46. 全排列】
- 细谈JVM垃圾回收与部分底层实现
- jquery概要--基础01
- js网页动画,如何做一款高逼格不失真的动画
- JAVA经典算法面试40题及答案
- http小型服务器搭建
- NodeJS中的UDP通信
热门文章
- 信用卡诈骗罪16个有效辩点
- 一文搞懂如何兼容苹果HomeKit?智汀助你轻松打造智慧家庭
- 平板/笔记本亮度调节工具halo(WINDOWS)
- 阿里云EMAS移动测试|快速掌握移动端兼容性测试技巧
- 数字电路34( 计数器—二进制加计数器)
- Android仿淘宝物流时间轴
- 编译一个java源程序文件,会产生多少个字节码文件
- SLAM Evaluation 之轨迹对齐论文翻译Closed-Form Solution of Absolute Orientation Using Orthonormal Matrices
- 一、学海无涯,再出发!【2020.02.14-25】
- FPGA 串口通信——通用模块