阅读视图

发现新文章,点击刷新页面。

全面详细的常用Linux命令汇总(2)

无论是Linux的新手还是老手,掌握一些常用命令都是必不可少的,熟练使用它们可以大大提高工作效率,成为工作中的得力助手。本文是常用Linux命令汇总系列文章的第二篇,全面详细的展示了10个与文档编辑相关的命令。

一览表

序号命令简述分类
1cat连接与查看文件内容文档编辑
2more分页显示大文件文档编辑
3less功能强大的文本查看器文档编辑
4head查看文件开头部分文档编辑
5tail查看文件结尾部分文档编辑
6vim强大的文本编辑器文档编辑
7sed批量编辑文本文件文档编辑
8awk对文本和数据进行处理的编程语言文档编辑
9grep强大的文本搜索工具文档编辑
10diff比较文件内容差异文档编辑

1. cat 命令

cat 命令主要用于查看文件内容,也可将多个文件合并输出,还能创建新文件。它会一次性将文件的全部内容输出到标准输出设备(通常是屏幕)。

语法格式

1
cat [参数] 文件

常用参数

1
2
3
4
5
6
-n    显示行号,会在输出的每一行前加上行号
-b 显示行号,但只对非空行进行编号
-s 压缩连续的空行,只显示一个空行
-E 在每一行的末尾显示 $ 符号
-T 将 Tab 字符显示为 ^I
-v 显示一些非打印字符

实例

(1)显示指定文件内容并显示非空行的行号

1
cat -b file1

image-20241114164504779

(2)把文件A的非空白行内容加上行号,之后将其附加到文件B中

1
cat -b file2 >> file3

image-20240320165734429

注意

  • cat命令默认会一次显示整个文件,如果文件过大可能会导致终端卡顿
  • cat命令可以用来创建新的空文件,但不能编辑文件

2. more 命令

more 命令用于分页显示文件内容,每次显示一屏。当文件内容较多时,使用 more 可以逐屏查看,避免内容过多在屏幕上滚动过快而难以阅读。

语法格式

1
more [参数] 文件

常用参数

1
2
3
4
5
6
7
8
+n    从笫n行开始显示
-n 定义屏幕大小为n行
+/pattern 在每个档案显示前搜寻该字串(pattern),然后从该字串前两行之后开始显示
-c 从顶部清屏,然后显示
-d 提示“Press space to continue,’q’ to quit(按空格键继续,按q键退出)”,禁用响铃功能
-l 忽略Ctrl+l(换页)字符
-s 把连续的多个空行显示为一行
-u 把文件内容中的下画线去掉

操作命令

1
2
3
4
5
<回车键>    向下n行,需要定义。默认为1行
<空格键> 向下滚动一屏
<Ctrl> + B 返回上一屏
= 输出当前行的行号
q 退出more

实例

(1)显示指定文件内容并从第 5 行开始显示

1
more +5 file1

image-20241114171900559

(2)从文件中查找第一个出现 34 字符串的行,并从该处前两行开始显示输出

1
more +/34 file1

image-20241114172040667

(3)设定每屏显示行数为 5

1
more -5 file1

image-20241114172319103

3. less 命令

less 功能更强大,支持向前和向后翻页,在文件中进行搜索,并且可以在查看文件时不加载整个文件到内存,对于非常大的文件更加高效。

语法格式

1
less [参数] 文件

常用参数

1
2
3
4
5
6
7
8
9
10
11
12
-b <缓冲区大小>    设置缓冲区的大小
-e 当文件显示结束后,自动离开
-f 强迫打开特殊文件,例如外围设备代号、目录和二进制文件
-g 只标志最后搜索的关键词
-i 忽略搜索时的大小写
-m 显示类似more命令的百分比
-N 显示每行的行号
-o <文件名> 将输出的内容在指定文件中保存起来
-Q 不使用警告音
-s 显示连续空行为一行
-S 行过长时将超出部分舍弃
-x <数字> 将"tab"键显示为规定的数字空格

操作命令

1
2
3
4
5
6
7
8
9
10
/字符串    向下搜索"字符串"的功能
?字符串 向上搜索"字符串"的功能
b 向上滚动一页
u 向上滚动半页
y 向上滚动一行
<空格键> 向下滚动一页
d 向下滚动半页
<回车键> 向下滚动一行
h 显示帮助界面
q 退出less

实例

(1)ps 查看进程信息并通过 less 分页显示

1
ps -ef |less

image-20241114173653083

(2)浏览多个文件

1
less file1 file2

提示:输入 :n 切换到下一个文件,输入 :p 切换上一个文件

image-20241114174041626

4. head 命令

head 命令用于显示文件的开头部分内容。默认情况下会显示文件的前 10 行内容。

语法格式

1
head [参数] 文件

常用参数

1
2
3
4
-q    隐藏文件名
-v 显示文件名
-c<数目> 显示的字节数
-n<行数> 显示的行数

实例

(1)显示指定文件的前 13 行

1
head -n 13 file1

image-20241114174815384

(2)显示指定文件除最后 39 行外的全部内容

1
head -n -39 file1

image-20241114175131721

(3)显示指定文件的前 100 个字节

1
head -c 100 file1

image-20241114175344903

5. tail 命令

tail 命令用于显示文件的结尾部分内容。默认情况下会显示文件的最后 10 行内容。

语法格式

1
tail [参数] 文件

常用参数

1
2
3
4
5
6
7
8
-f    循环读取
-q 不显示处理信息
-v 显示详细的处理信息
-c<数目> 显示的字节数
-n<行数> 显示的行数
--pid=PID 与-f合用,表示在进程ID,PID死掉之后结束
-q, --quiet, --silent 从不输出给出文件名的首部
-s, --sleep-interval=S 与-f合用,表示在每次反复的间隔休眠S秒

实例

显示指定文件的后 13 行

1
tail -n 13 file1

image-20241114175550073

6. vim 命令

vim 是强大的文本编辑器,支持多种操作模式,包括命令模式、输入模式和命令行模式。

语法格式

1
vim 文件

操作模式

  • 命令模式:控制光标移动,可对文本进行复制、粘贴、删除和查找等
  • 输入模式:正常的文本输入
  • 命令行模式:保存或退出文档,以及设置编辑环境

image-20241119201558539

1. 命令模式

用户启动 vim 便进入了命令模式,此状态下敲击键盘动作会被 vim 识别为命令,而非输入字符,比如按下 iao 就进入了输入模式,而按下 : 就进入了命令行模式。

1
2
3
4
5
6
7
8
9
10
11
i    切换到输入模式,在光标当前位置开始输入文本
a 切换到输入模式,在光标下一个位置开始输入文本
o(小写) 在当前行的下方插入一个新行,并进入输入模式
O(大写) 在当前行的上方插入一个新行,并进入输入模式
dd 剪切当前行
yy 复制当前行
p(小写) 粘贴剪贴板内容到光标下方
P(大写) 粘贴剪贴板内容到光标上方
u 撤销上一次操作
<Ctrl> + r 重做上一次撤销的操作
: 切换到命令行模式,以在最底一行输入命令

2. 输入模式

在输入模式中用户可以随意修改文本内容,当编写完成后可以使用 <ESC> 返回命令模式,进行其它操作。

1
2
3
4
5
6
<ENTER>    回车键,换行
<BACK SPACE> 退格键,删除光标前一个字符
<DELETE> 删除键,删除光标后一个字符
<HOME>/<END> 移动光标到行首/行尾
<Page Up>/<Page Down> 上/下翻页
<ESC> 退出输入模式,切换到命令模式

3. 命令行模式

在命令模式下按下 : 就进入了命令行模式,在命令行模式通过输入单个或多个字符的命令来实现丰富与连贯的操作。

1
2
3
4
5
6
:w    保存文件
:q 退出 Vim 编辑器
:wq 保存文件并退出 Vim 编辑器
:q! 强制退出 Vim 编辑器,不保存修改
:set nu (变量变更)显示行号
:set nonu (变量变更)取消行号

实例

使用 vim 打开指定文件

1
vim file1

image-20241114203405731

7. sed 命令

sed 是一种流编辑器,用于对文本进行非交互式的编辑操作,可以进行文本的替换、删除、插入等操作。

语法格式

1
sed [参数] [事件] 文件

常用参数

1
2
-e    以选项中指定的事件处理输入的文本文件
-n 仅显示事件处理后的结果

事件动作

1
2
3
4
5
6
a    新增,a的后面接字串,字串在下一行出现
c 取代,c的后面接字串,字串替换n1,n2之间的行
d 删除,删除行,d的后面通常不接字串
i 插入,i的后面接字串,字串在上一行出现
p 打印,将某个选择的数据输出,通常与参数 -n 一起运行
s 取代,通常搭配正则表达式

实例

(1)在指定文件第 6 行后添加一行,并将结果输出到标准输出设备

1
sed -e 6a跟在第6行后的一行 file1

image-20241114232322949

(2)在指定文件中搜索包含 13 的行并输出

1
sed -n 13p file1

image-20241114235444697

(3)替换指定文件中的内容更改为新内容

1
sed -e s/13/130/ file1

image-20241115000631362

8. awk 命令

awk 是一种用于处理文本文件的语言,它以行为单位处理文件内容,可以进行复杂的数据提取和分析。

语法格式

1
awk [参数] [处理规则] 文件

常用参数

1
2
3
-F <分隔符>    指定输入字段的分隔符,默认是空格
-v <变量名>=<值> 设置内部变量值。可以使用该选项将外部值传递给 awk 脚本中的变量
-f <脚本文件> 指定一个包含 awk 脚本的文件。这样可以在文件中编写较大的 awk 脚本,然后通过 -f 选项将其加载

内置变量

1
2
3
4
5
$0    保存当前行的内容
NR 记录号(行号),每处理完一条记录,NR值加1
NF 保存记录的字段数(总共保存的列数),$1,$2...$100
FS 输入字段分隔符,默认空格
OFS 输出字段分隔符

处理规则

1
2
3
4
BEGIN{}    BEGIN是在awk处理文本之前运行
// 使用的匹配规则
{} 循环(每次只处理一行数据)
END{} 当所有的处理全部执行完毕之后,执行END中的相关操作

实例

(1)打印指定文件内容的第一列

1
awk '{print $1}' file3

image-20241119115814152

(2)打印指定文件内容的第一列,并用分隔符指定列

1
awk -F':' '{print $1}' file3

image-20241119115951010

(3)打印指定文件内容的行数

1
awk 'END{print NR}' file3

image-20241119120225590

9. grep 命令

grep 命令用于在文件中搜索指定的模式。它可以搜索单个文件或多个文件,并输出包含匹配模式的行。

语法格式

1
grep [参数] 模式 文件

常用参数

1
2
3
4
5
6
-i    忽略大小写进行匹配
-v 反向查找,只打印不匹配的行
-n 显示匹配行的行号
-r 递归查找子目录中的文件
-l 只打印匹配的文件名
-c 只打印匹配的行数

实例

(1)在指定文件中搜索包含特定字符串的行

1
grep "/bin" file3

image-20241119121130878

(2)使用递归查找指定目录下所有文件包含指定字符串的行

1
grep -r "12" /linux

image-20241119121641346

10. diff 命令

diff 用于比较两个文件的差异。它会显示两个文件中不同的行,并可以以不同的格式输出差异信息。

语法格式

1
diff [参数] 文件1 文件2

常用参数

1
2
3
4
5
6
7
-u    显示完整的差异内容
-w 忽略空格和空行的差异
-r 递归比较目录下的所有文件和子目录
-q 仅判断两个文件是否不同,而不显示文件内容的差异
-c 显示上下文差异
-i 忽略大小写的差异
-y 以并列的方式显示差异内容

实例

(1)比较两个文件的差异

1
diff file1 file4

image-20241119125830112

(2)比较两个文件的差异,并以并列的方式展示差异

1
diff -y file1 file4

image-20241119130202656

生活百宝箱:点亮你的生活智慧

✇海Sky
作者 海Sky
{% music 西洲序,初月 / 曹敬鹏,https://music.163.com/song/media/outer/url?id=2606997888.mp3,https://p2.music.126.net/vCtY0DD0Z9PEmiCvn0Dxig==/109951166557423224.jpg?param=300y300, %} 热敷、冷敷,你知道多少? 热敷和冷敷是常见的物理疗法...

Python unittest 框架,强大的测试利器

1 前言

单元测试是软件开发中的重要环节,它是对软件中最小可测试单元进行检查和验证的过程。对于单元测试中单元的含义,一般要根据实际情况判定,如在 C 语言中单元指一个函数,在 Java 里单元指一个类,在图形化软件中可以指一个窗口或一个菜单等。总的来说,单元就是人为规定的最小的被测功能模块。

unittest 框架作为 Python 强大的单元测试工具,在软件测试中发挥着重要作用。其核心优势主要体现在以下几个方面:

  • 内置于 Python 标准库:作为 Python 标准库的一部分,unittest 框架无需额外安装即可使用,降低了项目的依赖成本。
  • 丰富的功能特性:框架提供了丰富的断言方法、测试用例组织方式、测试运行器等功能特性,满足了开发者多样化的测试需求。
  • 良好的兼容性与扩展性:unittest 框架与其他 Python 测试工具和库兼容良好,同时也支持开发者根据需要进行定制和扩展。

2 核心概念

  • Test Case(测试用例)

一个 TestCase 的实例就是一个测试用例,它是 unittest 框架中的基本单元。测试用例的方法必须以 test 开头,这样 unittest 框架才能识别并执行这些方法。

测试用例的执行顺序是按照方法名的 ASCII 值进行排序的,而不是按照书写的顺序。这意味着如果想要控制测试用例的执行顺序,不能仅仅依靠书写的先后顺序,需要通过合理命名方法名来实现。

在测试用例中,断言方法是判断被测对象行为是否符合预期的关键。例如,可以使用assertEqual()断言两个值是否相等,assertTrue()断言一个表达式是否为真,assertFalse()断言一个表达式是否为假等。如果断言失败,测试框架会抛出一个异常,表明测试用例未通过。

  • Test Suite(测试套件)

测试套件是将多个测试用例集合在一起执行的工具。它可以将不同的测试用例组织起来,形成一个更大的测试集合,方便进行批量测试。

可以通过多种方式构建测试套件。例如,可以使用unittest.TestSuite()实例化一个测试套件对象,然后通过addTest()方法逐个添加测试用例。也可以使用unittest.makeSuite()方法,根据一个测试类批量创建测试用例并添加到测试套件中。

测试套件还可以嵌套,即一个测试套件可以包含其他测试套件,这样可以更加灵活地组织测试用例。

  • Test Runner(测试运行器)

测试运行器是用来执行测试用例并返回执行结果的工具。它可以配合测试套件一起使用,执行测试套件中的所有测试用例,并将测试结果保存到TextTestResult实例中。

unittest.TextTestRunner()是一个常用的测试运行器,它提供了多种运行测试用例的方法。可以设置不同的参数来控制测试结果的显示详细程度,例如verbosity参数可以设置为 0、1 或 2,分别对应静默模式、默认模式和详细模式。

在详细模式下,测试运行器会显示每个测试用例的所有相关信息,包括测试用例的名称、执行结果、错误信息等,这对于调试和分析测试结果非常有帮助。

  • Test Fixture(测试夹具)

测试夹具在单元测试中起着至关重要的作用。它主要负责为测试用例提供一个稳定、一致的测试环境,包括环境搭建(setUp)和销毁(tearDown)。

setUptearDown方法可以在不同的级别生效。比如,在方法级别,setUp(self)会在每个测试方法执行前自动执行,用于准备测试数据和环境;tearDown(self)则在每个测试方法执行后自动执行,用于清理测试数据和环境。例如在测试数据库操作时,setUp可以建立数据库连接,准备测试数据,而tearDown可以关闭数据库连接,清理测试过程中产生的数据。在类级别,@classmethod装饰的setUpClass(cls)在每个测试类里,执行一次,在所有用例运行前执行;tearDownClass(cls)同样在每个测试类里,执行一次,在所有用例运行后执行。这对于一些需要在类级别进行初始化和清理的操作非常有用,比如创建和销毁一个复杂的对象实例。在模块级别,setUpModule()在每个模块里,执行一次,在所有用例运行前执行;tearDownModule()在每个模块里,执行一次,在所有用例运行后执行。可以用于一些全局的初始化和清理操作,比如初始化日志系统等。

通过这些不同级别的测试夹具,可以为每个测试用例、测试类或测试模块提供干净的测试环境,确保测试结果的准确性和可靠性。

3 用例编写与执行

3.1 编写测试用例

编写测试用例是使用 unittest 框架进行单元测试的关键步骤。以下是编写测试用例的一般步骤:

1. 导入模块

首先,需要导入 unittest 模块以及要测试的模块。例如,如果要测试一个名为my_module的模块,可以使用以下代码导入:

1
2
import unittest
from my_module import *

2. 创建测试类

创建一个测试类,该类继承自unittest.TestCase。测试类的名称应该能够清晰地表明它所测试的模块或功能。例如:

1
2
class MyTest(unittest.TestCase):
...

3. 定义测试方法

在测试类中,定义测试方法。测试方法的名称必须以test_开头,这样 unittest 框架才能识别它们为测试方法。例如:

1
2
3
def test_functionality(self):
result = add(2, 3)
self.assertEqual(result, 5)

def test_functionality(self):定义了一个测试方法。在这个方法中,可以编写具体的测试逻辑,包括调用被测试的函数或方法,使用断言方法验证结果是否符合预期。例如被测试的函数是 add,可以使用result = add(2, 3)测试方法,然后使用断言方法self.assertEqual(result, 5)来验证结果是否为 5。

4. 调用 main 方法运行测试用例

在测试模块的底部,可以使用unittest.main()方法来运行所有的测试用例,这个方法会自动发现并执行所有以test_开头的测试方法。例如:

1
2
if __name__ == '__main__':
unittest.main()

3.2 用例执行方式

1. 自动发现和执行测试用例

unittest 提供了一种自动发现测试用例的机制。默认情况下,它会在当前目录下查找以test开头的 Python 文件,并将其中以test_开头的方法识别为测试用例。

可以通过命令行参数来指定特定的目录进行测试用例的自动发现。例如,使用python -m unittest discover -s /path/to/directory命令可以在指定目录下查找测试用例并执行。

2. 执行指定用例

指定测试模块:可以通过命令行参数指定要执行的测试模块。例如,运行python -m unittest test_module命令,将会执行名为test_module的模块中的所有测试用例。

指定测试类:可以进一步指定要执行的测试类。例如,运行python -m unittest test_module.TestClass命令,将会执行test_module模块中的TestClass类中的所有测试用例。

指定测试方法:还可以指定要执行的具体测试方法。例如,运行python -m unittest test_module.TestClass.test_method命令,将会执行test_module模块中的TestClass类中的test_method方法。

指定文件路径:除了使用模块和类名,也可以直接指定测试文件的路径来执行其中的测试用例。例如,运行python -m unittest /path/to/test_file.py命令,将会执行指定文件中的所有测试用例。

4 实例展示

4.1 用于测试的类

以下是一个用于测试的简单类示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Calculator:
def add(self, a, b):
return a + b

def subtract(self, a, b):
return a - b

def multiply(self, a, b):
return a * b

def divide(self, a, b):
if b == 0:
raise ValueError("除数不能为零")
return a / b

这个类Calculator包含了四个基本的数学运算方法:加法、减法、乘法和除法。

4.2 测试用例

以下是使用 unittest 框架对Calculator类进行测试的测试用例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import unittest
from calculator import Calculator

class TestCalculator(unittest.TestCase):
def setUp(self):
self.calculator = Calculator()

def test_add(self):
result = self.calculator.add(5, 3)
self.assertEqual(result, 8)

def test_subtract(self):
result = self.calculator.subtract(8, 3)
self.assertEqual(result, 5)

def test_multiply(self):
result = self.calculator.multiply(4, 3)
self.assertEqual(result, 12)

def test_divide(self):
result = self.calculator.divide(10, 2)
self.assertEqual(result, 5)

with self.assertRaises(ValueError):
self.calculator.divide(10, 0)

if __name__ == '__main__':
unittest.main()

在这个测试用例中,首先创建了一个TestCalculator类,它继承自unittest.TestCase。在setUp方法中,创建了一个Calculator的实例,以便在每个测试方法中使用。

test_add方法测试了加法运算,调用Calculator类的add方法并使用断言self.assertEqual来验证结果是否为预期值;test_subtract方法测试减法运算,同理使用断言验证结果;test_multiply方法测试乘法运算;test_divide方法测试除法运算,分为两种情况:正常情况下验证结果是否正确;当除数为零时,使用self.assertRaises来验证是否抛出了 ValueError 异常。

4.3 详细解释

1. 测试用例结构

每个测试方法都以test_开头,这是 unittest 框架的要求,以便框架能够自动识别并执行这些方法。

在每个测试方法中,首先调用被测试的方法,然后使用断言来验证结果是否符合预期。

2. 断言的使用

self.assertEqual用于验证两个值是否相等。在加法、减法、乘法和除法的正常测试中,使用这个断言来验证计算结果是否正确。

self.assertRaises用于验证是否抛出了特定的异常。在除法测试中,当除数为零时,应该抛出ValueError异常,使用这个断言来验证这一行为。

3. setUp方法的作用

setUp方法在每个测试方法执行之前都会被调用,用于设置测试环境。在这个例子中,创建了一个Calculator的实例,以便在每个测试方法中都可以使用这个实例进行测试。

4.4 特别注意

1. 测试方法的独立性

每个测试方法应该是独立的,不应该依赖于其他测试方法的执行顺序或结果。这可以确保即使某个测试方法失败,其他测试方法仍然可以正常执行,并且便于定位问题。

2. 异常处理的测试

对于可能抛出异常的代码,应该进行异常处理的测试。在这个例子中,对除法运算中除数为零的情况进行了异常测试,确保代码在出现异常情况时能够正确处理。

3. 测试用例的全面性

测试用例应该尽可能覆盖各种可能的情况,包括正常情况和边界情况。例如,对于加法运算,可以测试正数、负数、零等不同的输入情况;对于除法运算,可以测试除数为正数、负数、零等情况。

4. 测试用例的可读性

测试用例的代码应该具有良好的可读性,以便其他开发人员能够理解测试的目的和方法。可以使用有意义的测试方法名称和注释来提高测试用例的可读性。

5 写在最后

unittest 框架在 Python 项目中具有至关重要的地位。它在提高代码质量方面表现出色,通过提供丰富的断言方法和严格的测试流程,能够及时发现代码中的潜在问题,确保代码的正确性和稳定性。在测试管理方面,unittest 框架提供了多种方式来组织和执行测试用例。测试套件可以将多个测试用例或测试类集中起来执行,方便管理大量的测试用例。同时,测试运行器可以生成详细的测试报告,帮助开发者快速了解测试结果,定位问题。此外,框架中的测试固件功能,如setUptearDown方法,使得测试环境的搭建和销毁更加方便,提高了测试的可重复性和可维护性。unittest 框架作为 Python 内置的单元测试框架,具有广泛的应用前景。在持续集成和持续部署(CI/CD)流程中,unittest 框架可以与其他工具结合使用,实现自动化测试,确保每次代码提交后都能进行全面的测试,及时发现问题并进行修复。在大型项目中,unittest 框架可以帮助开发者更好地管理和维护测试用例,提高开发效率和代码质量。此外,unittest 框架还具有良好的可扩展性。开发者可以根据项目的需求,自定义测试用例和测试套件,实现更加复杂的测试场景。同时,框架也可以与其他测试工具和框架结合使用,发挥各自的优势,共同提高软件测试的效率和质量。

总之,unittest 框架在 Python 项目中具有重要的优势和广阔的应用前景,是提高代码质量、保证软件稳定性的重要工具。

深入探究电子邮件三大协议

1 前言

电子邮件系统中,SMTP、POP 和 IMAP 这三种协议起着至关重要的作用。SMTP 负责邮件的发送,将邮件从发件人传输到邮件服务器,并在服务器之间转发。POP 负责邮件的接收,允许用户从邮件服务器下载邮件到本地设备进行离线阅读,下载后通常会从服务器删除此邮件。IMAP 也负责邮件的接收,它提供了更灵活的邮件管理功能,用户可以在多个设备上同步邮件状态,并且邮件始终保存在服务器上,方便随时访问和管理。这三大协议相互配合,共同构建了一个高效、稳定的电子邮件系统。

image-20240204233153143

2 SMTP 协议

SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,主要负责将邮件从发件人的邮件客户端传送到收件人的邮件服务器。它使用 TCP/IP 协议簇,建立在 FTP 文件传输服务之上,通过 “推送” 的方式传递信息,确保邮件能够可靠且有效地在不同系统之间传输。例如,当我们使用邮件客户端发送邮件时,SMTP 客户端会请求与 SMTP 服务器建立一个 TCP 连接,然后将邮件发送给服务器,服务器再将邮件传递给接收方邮件服务器。

image-20240908101409969

2.1 发展历史

SMTP 协议的发展可以追溯到 20 世纪 70 年代,当时 ARPANET 需要一种用于发送和接收电子邮件的协议。1980 年,网络中心发布了第一个 SMTP 协议标准 RFC 821,定义了发送邮件的格式,以及向服务器发送和接收电子邮件的功能,还包括服务器与客户端的命令等。1986 年 RFC 822 发布,为电子邮件提供了一个标准格式。随后又发布了一系列新的 SMTP 协议标准,如 RFC 974(传输管理)、RFC 1651(SMTP 的拓展)、RFC 1869(SMTP 服务器拓展)等。随着互联网的快速发展和电子邮件的广泛应用,SMTP 协议不断进行更新和改进,以适应日益增长的邮件传输需求和不断变化的网络环境,为电子邮件的可靠传输提供了重要的支持。

2.2 工作流程

  1. 建立连接

    • 客户端请求连接:SMTP 客户端尝试与 SMTP 服务器建立 TCP 连接,默认使用 25 端口,若加密连接则可能使用 465 端口。
    • 握手与域名确认:一旦连接建立,客户端向服务器发送 EHLO 命令,以表明客户端支持的扩展命令和 SMTP 版本等信息。服务器收到 EHLO 命令后,会返回一个 220 响应代码,表示服务器准备好接收命令。
  2. 邮件传输

    • 身份验证(如有需要):客户端发送 AUTH 命令,并按照服务器返回的支持方法将所需内容编码后发送回服务器。服务器对客户端提供的凭据进行验证,根据验证是否通过来判断是否允许继续发送邮件。
    • 指定发件人:客户端使用 MAIL FROM 命令指定邮件发送者的地址。服务器接收到该命令后,会检查发件人地址的合法性,成功则返回响应代码 250。
    • 指定收件人:客户端使用 RCPT TO 命令指定一个或多个邮件接收者的地址。服务器接收到该命令后,会检查每个收件人地址是否有效,是否愿意为该收件人接收邮件等,成功则返回响应代码 250。
    • 发送邮件内容:客户端使用 DATA 命令发送邮件正文和附件等内容,内容需按照相关的邮件格式规范编写。客户端在输入完邮件内容后,以一个单独的行,只包含一个英文句号 . 作为邮件内容的结束标识。
  3. 连接释放

    客户端使用 QUIT 命令向服务器发送结束通知,表示本次邮件发送会话结束。服务器接收到命令后,会返回一个响应代码,如 221 表示服务关闭传输通道。

2.3 通信举例

在 163.COM 服务器上的 Robert 发送邮件到 OUTLOOK.COM 服务器上的 John、Chris 和 Mary,这里假设 outlook 上没有 Chris 用户。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// T表示客户端,S表示服务器

S: 220 OUTLOOK.COM Simple Mail Transfer Service Ready // 服务器已准备好接收客户端的连接请求

T: EHLO 163.COM // 客户端向服务器表明身份
S: 250 OUTLOOK.COM // 服务器响应并告知客户端名称

T: MAIL FROM:<Robert@163.com> // 客户端指定邮件发件人地址
S: 250 OK // 服务器返回成功响应

T: RCPT TO:<John@outlook.com> // 客户端指定邮件第一个收件人地址
S: 250 OK // 服务器返回成功响应

T: RCPT TO:<Chris@outlook.com> // 客户端指定邮件第二个收件人地址
S: 550 No such user here // 服务器返回失败响应,失败原因为没有此用户

T: RCPT TO:<Mary@outlook.com> // 客户端指定邮件第三个收件人地址
S: 250 OK // 服务器返回成功响应

T: DATA // 客户端表示准备发送邮件内容
S: 354 Start mail input; end with <CRLF>.<CRLF> // 服务器提示客户端开始输入邮件内容

T: Beginning of content... // 客户端发送邮件的具体内容
T: ...End of content. // 客户端发送邮件的具体内容
T: . // 邮件内容结束
S: 250 OK // 服务器回应邮件接收成功

T: QUIT // 客户端请求结束会话
S: 221 OUTLOOK.COM Service closing transmission channel // 服务器回应关闭传输通道,本次交互结束

2.4 优势特点

  1. 应用广泛,几乎所有电子邮件系统都支持该协议,使得不同邮件服务器之间能够顺利传递邮件。
  2. 协议设计简单高效,一系列明确的命令和响应机制,使得邮件发送过程清晰明了。
  3. 可靠的传输机制,采用存储转发的方式传输邮件,即使传输过程出现问题,邮件也会被暂存在服务器。

3 POP 协议详解

POP(Post Office Protocol)即邮局协议,主要用于接收邮件。常用的是 POP3 版本,它使用 TCP 的 110 端口。POP3 采用 C/S 工作模式,默认使用 TCP/IP 协议进行传输,属于应用层协议。用户可以通过电子邮件客户端设置 POP3 服务器的地址等参数,连接服务器后下载邮件。但在客户端的操作(如删除邮件等)通常不会反馈到服务器上,且下载后服务器上的邮件可能会被删除。

image-20240908112059666

3.1 发展历史

在 1984 年之前,电子邮件的使用还处于探索阶段,用户需要直接登录到邮件服务器才能读取邮件,1984 年,早期版本 POP1 和 POP2 被制定出来,奠定了发展基础,但功能有所不足。直到 1998 年,POP3 成为互联网标准,广泛应用于电子邮件系统中,规定了如何将个人计算机连接到互联网的邮件服务器并下载电子邮件。随着互联网的发展,其它优秀的电子邮件接收协议如 IMAP 开始出现,POP3 面临竞争却仍在电子邮件领域占据重要地位。

3.2 工作流程

  1. 建立连接

    • 客户端请求连接:POP 客户端尝试与 POP 服务器建立 TCP 连接,默认使用 110 端口。
    • 身份验证:客户端向服务器发送 APOP 命令,提供用户名及响应 MD5 哈希值,服务器正确接收则返回 +OK 响应码,等待下一步操作。
  2. 邮件获取

    • 获取邮件列表:客户端发送 LIST 命令,请求获取邮箱中的邮件列表,服务器返回每封邮件的编号和大小等信息。
    • 获取特定邮件:客户端使用 RETR 命令加上邮件编号,请求获取特定的邮件内容,服务器将指定邮件的内容发送给客户端。
    • 删除邮件(可选):客户端使用 DELE 命令加上邮件编号,服务器会标记该邮件为待删除状态,但不会立即删除。
  3. 连接释放

    客户端使用 QUIT 命令向服务器发送结束通知,表示本次邮件发送会话结束。服务器接收到命令后,会返回一个响应代码,如 +OK,表示成功关闭连接,此时真正删除标记为待删除的邮件。

3.3 通信举例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// M表示客户端,S表示服务器

S: +OK POP3 server ready <Mary@outlook.com> // 服务器响应

M: APOP mary 5bfef7618cbf9ab828aedc9b3d0d58d4 // 客户端向服务器验证身份
S: +OK mary's maildrop has 2 messages (320 octets) // 身份验证成功并报告邮件数量

M: STAT // 客户端请求邮件状态
S: +OK 2 320 // 服务器响应邮件状态,数量为2,总大小为320字节

M: LIST // 客户端请求邮件列表
S: +OK 2 messages (320 octets) // 服务器响应邮件列表
S: 1 120 // 服务器列出所有邮件及其大小
S: 2 200 // 服务器列出所有邮件及其大小
S: . // 服务器结束响应

M: RETR 1 // 客户端请求获取第一封邮件
S: +OK 120 octets // 服务器成功响应
S: The entirety of the content. // 服务器发送邮件内容
S: . // 服务器结束响应

M: DELE 1 // 客户端请求删除第一封邮件
S: +OK message 1 deleted // 服务器成功响应

M: RETR 2 // 客户端请求获取第二封邮件
S: +OK 200 octets // 服务器成功响应
S: The entirety of the content. // 服务器发送邮件内容
S: . // 服务器结束响应

M: DELE 2 // 客户端请求删除第二封邮件
S: +OK message 2 deleted // 服务器成功响应

M: QUIT // 客户端请求结束会话
S: +OK dewey POP3 server signing off (maildrop empty) // 服务器成功响应

3.4 优势特点

  1. 支持离线访问,邮件已下载到本地设备,在无网环境下仍可查看邮件。
  2. 广泛支持,几乎所有的主流邮件客户端和邮件服务器都支持该协议。

4 IMAP 协议详解

IMAP(Internet Message Access Protocol)即互联网消息访问协议,同样用于接收和管理邮件。它可以在多台设备上同步和管理电子邮件,支持在线和离线两种访问模式。在服务端保留邮件的原始副本,用户可以在客户端直接对服务器上的邮件进行操作,如在线浏览、标记邮件等,且多个用户可同时访问并能感知其他用户的操作。

image-20240908112124476

4.1 工作流程

  1. 建立连接
    • 客户端请求连接:IMAP 客户端尝试与 IMAP 服务器建立 TCP 连接,默认使用 143 端口,若加密连接则可能使用 993 端口。
    • 身份验证:客户端使用 login 命令向服务器发送认证信息,通常是用户名和密码等,服务器返回 OK 响应码即为完成验证。
  2. 邮件操作
    • 选择邮箱:客户端使用 SELECT 命令选择要操作的邮箱,服务器返回关于该邮箱的信息,如邮件数量、未读邮件数量等。
    • 获取邮件内容:客户端使用 FETCH <编号> full 命令获取指定邮件的详细内容,如邮件的主题、发件人、日期、正文、附件等。
    • 获取头部信息:客户端使用 FETCH <编号> body[header] 命令获取指定邮件的头部信息。
    • 标记状态:客户端使用 FLAGS 命令标记邮件为已读、未读、重要等状态,服务器根据命令实时更新邮件的状态标志。
  3. 断开连接
    • 客户端使用 LOGOUT 命令选择断开与服务器的连接,服务器确认后,关闭连接通道。

4.2 通信举例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// C表示客户端,S表示服务器

S: * OK IMAP4rev1 Service Ready // 服务器响应

C: a001 login mary password // 登录用户名与密码
S: a001 OK LOGIN completed // 服务器登录成功响应

C: a002 select inbox // 选择操作的邮箱
S: * 18 EXISTS // 收件箱中有18封邮件
S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft) // 收件箱支持的邮件标志
S: * 2 RECENT // 最近有2封新邮件
S: * OK [UNSEEN 17] Message 17 is the first unseen message // 第17封邮件是第一封未读邮件
S: * OK [UIDVALIDITY 3857529045] UIDs valid // 邮件ID有效
S: a002 OK [READ-WRITE] SELECT completed // 操作完成且有读写权限

C: a003 fetch 12 full // 获取编号为12的邮件的详细内容
S: * 12 FETCH (FLAGS (\Seen) INTERNALDATE "17-Jul-1996 02:44:25 -0700" // ↓邮箱的详细内容↓
RFC822.SIZE 4286 ENVELOPE ("Wed, 6 Sep 2024 02:23:25 +0800 (CST)"
...
BODY ("TEXT" "PLAIN" ("CHARSET" "US-ASCII") NIL NIL "7BIT" 302892))
S: a003 OK FETCH completed // 服务器返回成功响应

C: a004 fetch 12 body[header] // 获取编号为12的邮件的头部信息
S: * 12 FETCH (BODY[HEADER] {342} // 头部信息的长度为342字节
S: Date: Wed, 6 Sep 2024 02:23:25 +0800 (CST) // 邮件的发送日期和时间
S: From: Robert <Robert@163.com> // 邮件的发件人
S: Subject: Three major email protocols // 邮件的主题
S: To: Mary@outlook.com // 邮件的收件人
S: Message-Id: <xxxxxxxxxxxxxxxxxx> // 邮件的唯一标识符
S: MIME-Version: 1.0 // 邮件的MIME版本
S: Content-Type: TEXT/PLAIN; CHARSET=US-ASCII // 邮件的内容类型和字符集
S: )
S: a004 OK FETCH completed // 服务器返回成功响应

C: a005 store 12 +flags \deleted // 修改编号为12的邮件的标志为“已删除”
S: * 12 FETCH (FLAGS (\Seen \Deleted)) // 编号为12的邮件的标志被成功修改
S: a005 OK +FLAGS completed // 服务器返回成功响应

C: a006 logout // 结束与服务器的连接
S: * BYE IMAP4rev1 server terminating connection // 服务器正在终止连接
S: a006 OK LOGOUT completed // 成功终止连接

4.3 优势特点

  1. 多设备同步,对邮件的操作均可实时同步到其他设备,避免了混乱和重复操作。
  2. 邮件检索高效,即使面对大量邮件,也能够迅速定位到目标邮件。
  3. 服务器端管理出色,邮件存于服务器,节省设备空间,还可灵活管理文件夹,便捷高效。

5 协议对比与选择

5.1 协议比对

5.1.1 SMTP 与 POP/IMAP 的区别

SMTP 主要负责将邮件从发件人的邮件客户端传送到收件人的邮件服务器,它侧重于邮件的发送和中继,是一种“推送”的协议,即主动将邮件从发件人一方推送给收件人一方的服务器,但不能“拉取”消息。而 POP 和 IMAP 则主要用于接收邮件,它们可以接收来自 SMTP 发出的邮件。例如,当用户使用邮件客户端撰写一封邮件并点击发送时,邮件会通过 SMTP 协议被推送到发件人的邮件服务器,然后再由发件人的邮件服务器根据收件人的地址将邮件转发给收件人的邮件服务器。而当收件人想要查看自己的邮件时,就可以通过 POP 或 IMAP 协议从自己的邮件服务器上拉取邮件到本地客户端进行查看。

5.1.2 POP 与 IMAP 的区别

POP 协议在客户端操作邮件时,如移动邮件或标记已读,这些更改不会同步到服务器。因此,当用户在其他设备上通过 POP 协议重新连接服务器时,邮件状态保持不变,如未读状态和原始位置。相比之下,IMAP 协议实现了客户端与服务器之间的双向通信,确保客户端的任何操作都会实时反映到服务器上,如标记邮件为已读或移动到特定文件夹。

image-20240907191310308

5.2 选择场景

**日常办公:**对于经常需要在不同设备上查看邮件的人来说,IMAP 协议是更好的选择。它可以确保在公司电脑、家庭电脑和手机等多个设备上的邮件状态同步,方便随时处理邮件,避免遗漏重要信息。例如,在电脑查看了一封邮件并标记为已读,在手机上也会同步显示为已读状态,避免在重复内容上浪费时间,提高工作效率。

**移动办公:**在移动办公或出差时,POP 协议的离线访问功能具有一定优势。用户可以在有网络的时候将邮件下载到本地设备,在没有网络的情况下仍然可以查看邮件,不影响工作进度。例如,在乘坐飞机或前往网络信号不好的地区时,预先下载的邮件可以随时查阅。

**大规模邮件收发:**对于企业或组织需要大规模发送邮件的情况,SMTP 协议的稳定性和广泛适用性至关重要。它能够确保邮件准确无误地传输到收件人的邮件服务器,即使在高并发的情况下也能保持良好的性能。例如,企业进行营销活动或发送通知邮件时,SMTP 协议可以保证邮件的快速发送和传递。同时,对于接收大量邮件的用户来说,IMAP 协议的服务器端管理功能可以更好地应对。它可以将邮件分类整理在服务器上,用户可以通过不同的设备随时访问和管理邮件,而不会因为邮件数量过多而导致本地设备存储压力过大。

6 写在最后

电子邮件成功发展至今,离不开 SMTP、POP 和 IMAP 三大协议的共同支撑。SMTP 负责邮件的发送,POP/IMAP 负责邮件的下载,相互协作,不断优化升级,满足在各种通信场景下的不同需要。

部分资料参考于 RFC 文档

掌握Markdown技巧,轻松应对写作需求

Markdown 是一种轻量级标记语言,它以简洁易读的文本格式来编写文档。

特点

  1. 简单易学:语法简洁明了,容易上手。
  2. 可读性高:纯文本形式,便于阅读和理解。
  3. 跨平台:在各种操作系统和设备上都能使用。
  4. 广泛应用:常用于文档编写、博客文章、技术文档等。

注意:

本文 Markdown 语法使用 VSCode 编辑并使用其插件 Markdown Preview Enhanced 预览。

1 基本语法

最简单的语法,通常在大部分编辑器中都可以使用。

1.1 标题

使用一定数量的#标记标题,#的数量代表标题的级别。

1
2
3
4
5
6
7
8
9
10
11
# 一级标题

## 二级标题

### 三级标题

#### 四级标题

##### 五级标题

###### 六级标题

image-20240520214045132

使用三个以上的=-在后一行可以标记一级标题和二级标题。

1
2
3
4
5
一级标题
===

二级标题
---

image-20240520214208160

1.2 段落

段落无特殊格式,直接编写文字就可以;换行需要在段落后面加一个空行表示重新开始一个新段落。

image-20240520214301969

1.3 强调

使用一定数量的*_标记加粗、倾斜等效果表示强调,它需要在目标文本的前后添加相同相等的符号来标记开始和结束。推荐使用*

1
2
3
4
5
6
7
8
9
10
11
**加粗**

*倾斜*

***加粗倾斜***

__加粗__

_倾斜_

___加粗倾斜___

image-20240520215755614

1.4 分割线

使用三个以上的*-_标记分割线,需要在单独一行使用。推荐使用-

1
2
3
4
5
***

---

___

image-20240520220402859

1.5 引用

使用>标记区块引用,使用两个以上的>标记嵌套的区块引用,其它大部分语法都可以嵌套在引用其中。

1
2
3
> 区块引用
>
>> 嵌套的区块引用

image-20240520221402730

1.6 列表

列表分为无序和有序两种。使用*+-标记无序列表,使用数字.标记有序列表。列表可以嵌套,有序列表可以自定义序号。

1
2
3
4
5
6
7
8
9
* 无序列表

+ 无序列表

- 无序列表
- 嵌套的无序列表

1. 有序列表
5. 打乱的有序列表

image-20240520222930114

1.7 链接

使用[]()标记一个超链接,链接文本放在[]中,链接地址放在()中,还可以使用尖括号<>将URL或Email地址变成可点击链接。

1
2
3
4
5
[爱吃猫的鱼BLOG](https://talen.top)

<https://talen.top>

<talen2004@163.com>

image-20240520231339720

1.8 图片

使用![]()标记一张图片,图片描述放在[]中,图片地址放在()中,本地图片使用相对地址引用,网络图片使用网络链接引用。

1
2
3
![本地图片](/2024-05-19_hd.jpg)

![网络图片](https://bing.mcloc.cn/img/2024/05/19/2024-05-19_hd.jpg)

image-20240520232035205

1.9 代码

使用``标记行内代码,内容放在``中。

1
`Markdown`语法

image-20240520233418426

1.10 转义

使用\将格式化字符转义为原义,可转移字符有\ * _ {} [] () # + - . ! |等。

1
\*不要倾斜\*

image-20240520232430817

2 拓展语法

拓展语法可能在某些编辑器中无法使用。

2.1 表格

使用|分割每列、三个以上的-创建每列标题来标记表格,在---左右使用:表示对其方式。

1
2
3
4
| 默认 | 左对齐 | 居中 | 右对齐 |
| --- | :--- | :---: | ---: |
| 内容 | 内容 | 内容 | 内容 |
| 内容 | 内容 | 内容 | 内容 |

image-20240520234516064

2.2 代码块

使用两个```在代码上下标记代码块,第一个```后指定语言可将代码高亮显示。

1
2
3
4
5
6
```json
{
"Name": "Lisa",
"Age": 25
}
```

image-20240520235420231

2.3 脚注

使用[^][^]:组合标记脚注,脚注标题在^后,脚注内容在:后。

1
2
3
4
5
第一个脚注[^1]和第二个脚注[^2]

[^1]: 第一个脚注的内容。

[^2]: 第二个脚注的内容。

image-20240521000344993

2.4 任务列表

使用- [ ]标记任务列表,[]中添加×表示复选框。

1
2
- [x] 完成
- [ ] 未完成

image-20240521000918425

2.5 删除线

使用~~标记删除线,在目标内容前后添加~~

1
~~删除线~~

image-20240521001341326

2.6 内容目录

使用[TOC]标记一个目录,它根据标题自动生成。

1
[TOC]

image-20240521002334233

2.7 公式

若支持 LaTeX 公式,$表示行内公式,$$表示整行公式。更多相关知识可参阅 LaTeX 入门 - OI Wiki

1
2
3
4
5
6
7
8
9
10
11
12
13
$$
\begin{Bmatrix}
a & b \\
c & d
\end{Bmatrix}
$$
$$
\begin{CD}
A @>a>> B \\
@VbVV @AAcA \\
C @= D
\end{CD}
$$

image-20240521004041255

3 进阶使用

Markdown 语法还支持 HTML 标签,所以可以使用 HTML 标签来完成一些进阶效果。

3.1 复杂表格

使用 HTML 标签可以让表格实现合并单元格等效果,rowspan 为跨行合并,colspan 为跨列合并,style 可以添加 CSS 样式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<table>
<tr>
<th rowspan="2" style="color:#dea71f">值班人员</th>
<th style="color:#fc5531">星期一</th>
<th style="color:#fc5531">星期二</th>
<th style="color:#fc5531">星期三</th>
<th style="color:#fc5531">星期四</th>
</tr>
<tr>
<td>李强</td>
<td>张明</td>
<td colspan="2">王平</td>
</tr>
</table>

image-20240521164118238

3.2 更改文本

使用 HTML 标签还可以给文本添加各种 CSS 样式,如改变颜色、字体、大小等。

1
2
3
4
5
6
<font face="微软雅黑">微软雅黑</font>
<font face="STCAIYUN">华文彩云</font>
<font color=red>红色</font>
<font color=#008000>绿色</font>
<font size=5>尺寸5</font>
<font color=green face="黑体" size=5>绿色黑体尺寸5</font>

image-20240521164733868

3.3 特殊标志

使用<kbd> <sup> <sub>等标签可以实现键盘文本、上下标等效果。

1
2
3
4
5
复制:<kbd>Ctrl</kbd>+<kbd>C</kbd>

数学:3<sup>2</sup>=9

化学:CO<sub>2</sub>

image-20240521165945978

3.4 调整图片

使用<img>标签配合 CSS 样式可以调整图片。

1
<img src="https://bing.mcloc.cn/img/2024/05/19/2024-05-19_hd.jpg" width = "200" align="right" />

image-20240521170634199

4 高级技巧

Markdown 语法还有很多使用技巧需要探索发现。

4.1 插入bash64图片

将图片转化为 Bash64 编码,可以直接插入在![]()()中使用。推荐一个编码网站:图片转BASE64

1
2
![base64](data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAeAB4.....dG7tzQTdtNWrn//2Q==)
.....内容已省略

image-20240521172424558

4.2 各类图表

Markdown 语法除了支持公式外,还支持多种图表。本节采集于网络,仅供参考。

1、横向流程图

1
2
3
4
5
6
7
8
```mermaid
graph LR
A[方形] -->B(圆角)
B --> C{条件a}
C -->|a=1| D[结果1]
C -->|a=2| E[结果2]
F[横向流程图]
```

image-20240521173659952

2、竖向流程图

1
2
3
4
5
6
7
8
```mermaid
graph TD
A[方形] --> B(圆角)
B --> C{条件a}
C --> |a=1| D[结果1]
C --> |a=2| E[结果2]
F[竖向流程图]
```

image-20240521173734568

3、UML时序图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
```mermaid
%% 时序图例子,-> 直线,-->虚线,->>实线箭头
sequenceDiagram
participant 张三
participant 李四
张三->王五: 王五你好吗?
loop 健康检查
王五->王五: 与疾病战斗
end
Note right of 王五: 合理 食物 <br/>看医生...
李四-->>张三: 很好!
王五->李四: 你怎么样?
李四-->王五: 很好!
```

image-20240521173831504

4、甘特图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
```mermaid
%% 语法示例
gantt
dateFormat YYYY-MM-DD
title 软件开发甘特图
section 设计
需求 :done, des1, 2014-01-06,2014-01-08
原型 :active, des2, 2014-01-09, 3d
UI设计 : des3, after des2, 5d
未来任务 : des4, after des3, 5d
section 开发
学习准备理解需求 :crit, done, 2014-01-06,24h
设计框架 :crit, done, after des2, 2d
开发 :crit, active, 3d
未来任务 :crit, 5d
耍 :2d
section 测试
功能测试 :active, a1, after des3, 3d
压力测试 :after a1 , 20h
测试报告 : 48h
```

image-20240521173851730

5 工具

编写 Markdown 有很多好用的工具,就像编写文档有 Word 一样。

PC端:Typora(推荐)、Obsidian、VSCode等

移动端:Obsidian、坚果云Markdown等

Web端:Cmd MarkdownEditor.md


我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=3bjscq0kgso4k

正则表达式的基本介绍与正则大全

正则表达式(Regular Expression)又称规则表达式,在代码中常简写为RegexRegexpRE,它是一种文本模式,包括普通字符(例如a到z之间的字母)和特殊字符(称为"元字符")。

作用

  1. 文本验证:用于检查输入的文本是否符合特定的格式要求,如验证电子邮件、电话号码等。
  2. 文本搜索和替换:可以在文本中查找特定模式的内容,并进行替换操作。
  3. 数据提取:从文本中提取出符合特定模式的部分内容。
  4. 语法分析:在某些编程领域中,用于分析和理解代码的结构。

1 语法

一个正则表达式是一种从左到右匹配主体字符串的模式,它可以从一个基础字符串中根据一定的匹配模式替换文本中的字符串、验证表单、提取字符串等等。

1.1 基本匹配

由一些字符(如字母、数字或符号)组成的最简单的正则表达式。

实例

1
my

image-20240511224117653

1.2 元字符

正则表达式主要依赖于元字符。 元字符不代表他们本身的字面意思而是有有特殊的含义。

元字符描述
.匹配除换行符以外的任意字符
[ ]字符类。匹配方括号内的任意字符
[^ ]否定的字符种类。匹配除了方括号里的任意字符
*匹配前面的子表达式零次或多次
+匹配前面的子表达式一次或多次
?匹配前面的子表达式零次或一次
{n,m}匹配前面的子表达式最少n次最多m次
( )匹配分组。组合一个子表达式
|或运算符,匹配符号前或后的字符
\转义字符,用于匹配一些保留的字符
^从开头进行匹配
$从末端进行匹配

1.2.1 点 .

.匹配任意单个字符,但不匹配换行符。

示例1

1
.

image-20240512143846833

示例2

1
.n

image-20240512143933842

1.2.2 字符类

方括号[]用来指定一个字符类,在方括号中的字符都将被匹配。字符类不会被顺序影响,还可以使用连字符-来指定范围。

示例1

1
[aeiou]

image-20240512144913169

示例2

1
[a-m]

image-20240512145419367

否定字符类

当符号^用在方括号[]内表示这个字符类是否定的。

示例1

1
[^aeiou]

image-20240512145928931

示例2

1
[^a-m]

image-20240512150004372

1.2.3 重复

当一个子表达式后面跟着字符+ * ?,是用来指定匹配该子表达式的次数。

1.2.3.1 星号 *

*匹配在*之前的字符出现大于等于0次。

示例1

1
e*

需要注意的是,e 出现0次的地方也会被标记

image-20240512151436387

示例2

匹配所有字符

1
.*

image-20240512152644347

1.2.3.2 加号 +

+匹配+之前的字符出现大于等于1次。

示例1

1
e+

image-20240512153536137

示例2

匹配以 e 开头,以 u 结尾的内容

1
e.+u

image-20240512153839436

1.2.3.3 问号 ?

匹配之前的字符出现0或者1次,即表示前面的字符是可选的。

示例

1
ou?n

image-20240512154651440

1.2.3.4 花括号 {}

{}常用来限定子表达式可以出现的次数。比如{n,m}表示出现最少 n 次最多 m 次,{n,}表示出现最少 n 次,{,m}表示出现最多 m 次,{n}表示固定出现 n 次。

示例1

1
e{2,3}

image-20240512155501711

示例2

1
e{2,}

image-20240512160016217

示例3

1
e{3}

image-20240512160051826

1.2.4 匹配分组

括号()用来指定一个子表达式,在括号中的内容会被看作一个整体。比如 (xy)* 匹配连续出现零个或多个的 xy,而 xy* 则匹配连续出现零个或多个的 y

示例1

1
(love)+

image-20240512162059930

示例2

1
([at])r

image-20240512164518517

1.2.5 或运算符 |

|用于判断条件,表示或者。

示例

1
a|t|es

image-20240512165004816

1.2.6 转义

反斜线\用于将特殊字符转义为原义字符,特殊字符如{ } [ ] / \ + * . $ ^ | ?

示例

1
y\.

image-20240512165940893

1.2.7 锚点

锚点可以匹配指定开头或结尾的字符串。^ 指定开头,$ 指定结尾。

示例1

1
^Regular

image-20240512172014524

示例2

1
Expression$

image-20240512172057858

1.3 简写字符集

简写描述
\w匹配所有字母数字,等同 [a-zA-Z0-9_]
\W匹配所有非字母数字,等同 [^\w]
\d匹配数字,等同 [0-9]
\D匹配非数字,等同 [^\d]
\s匹配所有空格字符,等同 [\t\n\f\r\p{Z}]
\S匹配所有非空格字符: [^\s]
\f匹配一个换页符
\n匹配一个换行符
\r匹配一个回车符
\t匹配一个制表符
\v匹配一个垂直制表符
\p匹配 CR/LF,等同 \r\n

需要注意的是,\s \S \f \n \r \t \v \p 所匹配的字符均为非打印字符

1.4 断言

断言分为先行断言和后发断言,它们都属于非捕获组(用于匹配模式,但不包括在匹配列表中)。用来筛选指定条件的匹配结果。

需要注意的是,断言必须包含在分组()

符号描述
?=正先行断言-存在
?!负先行断言-排除
?<=正后发断言-存在
?<!负后发断言-排除

1.4.1 正先行断言 ?=

正先行断言的筛选条件为匹配字符其后跟随断言中定义的格式。

示例

1
my(?=\shometown)

image-20240512181224256

1.4.2 负先行断言 ?!

负先行断言的筛选条件为匹配字符其后不跟随断言中定义的格式。

示例

1
my(?!\shometown)

image-20240512231317412

1.4.3 正后发断言 ?<=

正后发断言的筛选条件为匹配字符其前跟随断言中定义的格式。

1
(?<=my)self

image-20240512232345325

1.4.4 负后发断言 ?<!

负后发断言的筛选条件为匹配字符其前不跟随断言中定义的格式。

1
(?<!my)self

image-20240512232406235

2 标记

标记也称为修饰符,作为额外的匹配策略用于修改表达式的搜索结果。标志可以任意组合使用,它也是正则表达式中的一部分。

标志描述
g全局搜索
i忽略大小写
m多行匹配

2.1 全局搜索

标记 g 用于全局搜索。即不仅返回第一个匹配结果,而是全部匹配结果。在语法章节中所有的示例均使用全局搜索。

示例

1
/r/g

image-20240513000657127

2.1 忽略大小写

标记 i 用于忽略大小写。匹配的字符可以是大写或者小写。

示例

1
/r/gi

image-20240513000706053

2.3 多行匹配

标记 m 用于多行匹配。比如前面说到的锚点^ $,如果想在每行的开头结尾生效,就需要使用标记 m

示例

1
/^Regular/gm

image-20240513002324588

3 常用正则

火车车次

1
/^[GCDZTSPKXLY1-9]\d{1,4}$/

手机机身码(IMEI)

1
/^\d{15,17}$/

必须带端口号的网址(或ip)

1
/^((ht|f)tps?:\/\/)?[\w-]+(\.[\w-]+)+:\d{1,5}\/?$/

网址(URL)

1
/^(((ht|f)tps?):\/\/)?([^!@#$%^&*?.\s-]([^!@#$%^&*?.\s]{0,63}[^!@#$%^&*?.\s])?\.)+[a-z]{2,6}\/?/

统一社会信用代码

1
/^[0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}$/

统一社会信用代码(宽松匹配)(15位/18位/20位数字/字母)

1
/^(([0-9A-Za-z]{15})|([0-9A-Za-z]{18})|([0-9A-Za-z]{20}))$/

迅雷链接

1
/^thunderx?:\/\/[a-zA-Z\d]+=$/

ed2k链接(宽松匹配)

1
/^ed2k:\/\/\|file\|.+\|\/$/

磁力链接(宽松匹配)

1
/^magnet:\?xt=urn:btih:[0-9a-fA-F]{40,}.*$/

子网掩码(不包含 0.0.0.0)

1
/^(254|252|248|240|224|192|128)\.0\.0\.0|255\.(254|252|248|240|224|192|128|0)\.0\.0|255\.255\.(254|252|248|240|224|192|128|0)\.0|255\.255\.255\.(255|254|252|248|240|224|192|128|0)$/

linux"隐藏文件"路径

1
/^\/(?:[^/]+\/)*\.[^/]*/

linux文件夹路径

1
/^\/(?:[^/]+\/)*$/

linux文件路径

1
/^\/(?:[^/]+\/)*[^/]+$/

window"文件夹"路径

1
/^[a-zA-Z]:\\(?:\w+\\?)*$/

window下"文件"路径

1
/^[a-zA-Z]:\\(?:\w+\\)*\w+\.\w+$/

股票代码(A股)

1
/^(s[hz]|S[HZ])(000[\d]{3}|002[\d]{3}|300[\d]{3}|600[\d]{3}|60[\d]{4})$/

大于等于0,小于等于150,支持小数位出现5,如145.5,用于判断考卷分数

1
/^150$|^(?:\d|[1-9]\d|1[0-4]\d)(?:\.5)?$/

html注释

1
/<!--[\s\S]*?-->/g

md5格式(32位)

1
/^[a-fA-F0-9]{32}$/

GUID/UUID

1
/^[a-f\d]{4}(?:[a-f\d]{4}-){4}[a-f\d]{12}$/i

版本号(version)格式必须为X.Y.Z

1
/^\d+(?:\.\d+){2}$/

视频(video)链接地址(视频格式可按需增删)

1
/^https?:\/\/(.+\/)+.+(\.(swf|avi|flv|mpg|rm|mov|wav|asf|3gp|mkv|rmvb|mp4))$/i

图片(image)链接地址(图片格式可按需增删)

1
/^https?:\/\/(.+\/)+.+(\.(gif|png|jpg|jpeg|webp|svg|psd|bmp|tif))$/i

24小时制时间(HH:mm:ss)

1
/^(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d$/

12小时制时间(hh:mm:ss)

1
/^(?:1[0-2]|0?[1-9]):[0-5]\d:[0-5]\d$/

base64格式

1
/^\s*data:(?:[a-z]+\/[a-z0-9-+.]+(?:;[a-z-]+=[a-z0-9-]+)?)?(?:;base64)?,([a-z0-9!$&',()*+;=\-._~:@/?%\s]*?)\s*$/i

数字/货币金额(支持负数、千分位分隔符)

1
/^-?\d{1,3}(,\d{3})*(\.\d{1,2})?$/

银行卡号(10到30位,覆盖对公/私账户,参考微信支付

1
/^[1-9]\d{9,29}$/

中文姓名

1
/^(?:[\u4e00-\u9fa5·]{2,16})$/

英文姓名

1
/(^[a-zA-Z][a-zA-Z\s]{0,20}[a-zA-Z]$)/

车牌号(新能源)

1
/^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-HJ-NP-Z](([DF]((?![IO])[a-zA-Z0-9](?![IO]))[0-9]{4})|([0-9]{5}[DF]))$/

车牌号(非新能源)

1
/^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-HJ-NP-Z][A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]$/

车牌号(新能源+非新能源)

1
/^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-HJ-NP-Z][A-HJ-NP-Z0-9]{4,5}[A-HJ-NP-Z0-9挂学警港澳]$/

手机号(mobile phone)中国(严谨),根据工信部2019年最新公布的手机号段

1
/^(?:(?:\+|00)86)?1(?:(?:3[\d])|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\d])|(?:9[01256789]))\d{8}$/

手机号(mobile phone)中国(宽松),只要是13、14、15、16、17、18、19开头即可

1
/^(?:(?:\+|00)86)?1[3-9]\d{9}$/

手机号(mobile phone)中国(最宽松),只要是1开头即可,如果你的手机号是用来接收短信,优先建议选择这一条

1
/^(?:(?:\+|00)86)?1\d{10}$/

日期(宽松)

1
/^\d{1,4}(-)(1[0-2]|0?[1-9])\1(0?[1-9]|[1-2]\d|30|31)$/

日期(严谨,支持闰年判断)

1
/^(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29)$/

中国省

1
/^浙江|上海|北京|天津|重庆|黑龙江|吉林|辽宁|内蒙古|河北|新疆|甘肃|青海|陕西|宁夏|河南|山东|山西|安徽|湖北|湖南|江苏|四川|贵州|云南|广西|西藏|江西|广东|福建|台湾|海南|香港|澳门$/

可以被moment转化成功的时间 YYYYMMDD HH:mm:ss

1
/^\d{4}([/:-\S])(1[0-2]|0?[1-9])\1(0?[1-9]|[1-2]\d|30|31) (?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d$/

email(邮箱)

1
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/

座机(tel phone)电话(国内),如: 0341-86091234

1
/^(?:(?:\d{3}-)?\d{8}|^(?:\d{4}-)?\d{7,8})(?:-\d+)?$/

身份证号(1代、15位数字)

1
/^[1-9]\d{7}(?:0\d|10|11|12)(?:0[1-9]|[1-2][\d]|30|31)\d{3}$/

身份证号(2代、18位数字),最后一位是校验位,可能为数字或字符X

1
/^[1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\d|30|31)\d{3}[\dXx]$/

身份证号,支持1/2代(15位/18位数字)

1
/^\d{6}((((((19|20)\d{2})(0[13-9]|1[012])(0[1-9]|[12]\d|30))|(((19|20)\d{2})(0[13578]|1[02])31)|((19|20)\d{2})02(0[1-9]|1\d|2[0-8])|((((19|20)([13579][26]|[2468][048]|0[48]))|(2000))0229))\d{3})|((((\d{2})(0[13-9]|1[012])(0[1-9]|[12]\d|30))|((\d{2})(0[13578]|1[02])31)|((\d{2})02(0[1-9]|1\d|2[0-8]))|(([13579][26]|[2468][048]|0[048])0229))\d{2}))(\d|X|x)$/

护照(包含香港、澳门)

1
/(^[EeKkGgDdSsPpHh]\d{8}$)|(^(([Ee][a-fA-F])|([DdSsPp][Ee])|([Kk][Jj])|([Mm][Aa])|(1[45]))\d{7}$)/

帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线组合

1
/^[a-zA-Z]\w{4,15}$/

中文/汉字

1
/^(?:[\u3400-\u4DB5\u4E00-\u9FEA\uFA0E\uFA0F\uFA11\uFA13\uFA14\uFA1F\uFA21\uFA23\uFA24\uFA27-\uFA29]|[\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0])+$/

小数(支持科学计数)

1
/^[+-]?(\d+([.]\d*)?([eE][+-]?\d+)?|[.]\d+([eE][+-]?\d+)?)$/

只包含数字

1
/^\d+$/

html标签(宽松匹配)

1
/<(\w+)[^>]*>(.*?<\/\1>)?/

匹配中文汉字和中文标点

1
/[\u4e00-\u9fa5|\u3002|\uff1f|\uff01|\uff0c|\u3001|\uff1b|\uff1a|\u201c|\u201d|\u2018|\u2019|\uff08|\uff09|\u300a|\u300b|\u3008|\u3009|\u3010|\u3011|\u300e|\u300f|\u300c|\u300d|\ufe43|\ufe44|\u3014|\u3015|\u2026|\u2014|\uff5e|\ufe4f|\uffe5]/

qq号格式正确

1
/^[1-9][0-9]{4,10}$/

数字和字母组成

1
/^[A-Za-z0-9]+$/

英文字母

1
/^[a-zA-Z]+$/

小写英文字母组成

1
/^[a-z]+$/

大写英文字母

1
/^[A-Z]+$/

密码强度校验,最少6位,包括至少1个大写字母,1个小写字母,1个数字,1个特殊字符

1
/^\S*(?=\S{6,})(?=\S*\d)(?=\S*[A-Z])(?=\S*[a-z])(?=\S*[!@#$%^&*? ])\S*$/

用户名校验,4到16位(字母,数字,下划线,减号)

1
/^[\w-]{4,16}$/

ip-v4[:端口]

1
/^((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.){3}(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])(?::(?:[0-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5]))?$/

ip-v6[:端口]

1
/(^(?:(?:(?:[0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$)|(^\[(?:(?:(?:[0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))\](?::(?:[0-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5]))?$)/i

16进制颜色

1
/^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3}|[a-fA-F0-9]{8}|[a-fA-F0-9]{4})$/

微信号(wx),6至20位,以字母开头,字母,数字,减号,下划线

1
/^[a-zA-Z][-_a-zA-Z0-9]{5,19}$/

邮政编码(中国)

1
/^(0[1-7]|1[0-356]|2[0-7]|3[0-6]|4[0-7]|5[1-7]|6[1-7]|7[0-5]|8[013-6])\d{4}$/

中文和数字

1
/^((?:[\u3400-\u4DB5\u4E00-\u9FEA\uFA0E\uFA0F\uFA11\uFA13\uFA14\uFA1F\uFA21\uFA23\uFA24\uFA27-\uFA29]|[\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0])|(\d))+$/

不能包含字母

1
/^[^A-Za-z]*$/

java包名

1
/^([a-zA-Z_]\w*)+([.][a-zA-Z_]\w*)+$/

mac地址

1
/^(([a-f0-9][0,2,4,6,8,a,c,e]:([a-f0-9]{2}:){4})|([a-f0-9][0,2,4,6,8,a,c,e]-([a-f0-9]{2}-){4}))[a-f0-9]{2}$/i

匹配连续重复的字符

1
/(.)\1+/

数字和英文字母组成,并且同时含有数字和英文字母

1
/^(?=.*[a-zA-Z])(?=.*\d).+$/

香港身份证

1
/^[a-zA-Z]\d{6}\([\dA]\)$/

澳门身份证

1
/^[1|5|7]\d{6}\(\d\)$/

台湾身份证

1
/^[a-zA-Z][0-9]{9}$/

大写字母,小写字母,数字,特殊符号 @#$%^&*~()-+=` 中任意3项密码

1
/^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![A-Z\W_!@#$%^&*`~()-+=]+$)(?![a-z0-9]+$)(?![a-z\W_!@#$%^&*`~()-+=]+$)(?![0-9\W_!@#$%^&*`~()-+=]+$)[a-zA-Z0-9\W_!@#$%^&*`~()-+=]/

ASCII码表中的全部的特殊字符

1
/[\x21-\x2F\x3A-\x40\x5B-\x60\x7B-\x7E]+/

正整数,不包含0

1
/^\+?[1-9]\d*$/

负整数,不包含0

1
/^-[1-9]\d*$/

整数

1
/^(?:0|(?:-?[1-9]\d*))$/

浮点数

1
/^(-?[1-9]\d*\.\d+|-?0\.\d*[1-9]\d*|0\.0+)$/

浮点数(严格)

1
/^(-?[1-9]\d*\.\d+|-?0\.\d*[1-9])$/

email(支持中文邮箱)

1
/^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/

域名(非网址,不包含协议)

1
/^([0-9a-zA-Z-]{1,}\.)+([a-zA-Z]{2,})$/

军官/士兵证

1
/^[\u4E00-\u9FA5](字第)([0-9a-zA-Z]{4,8})(号?)$/

户口薄

1
/(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/

4 备注

4.1 Regex101

地址:regex101.com

正则表达式测试器,具有语法突出显示、解释、备忘单等功能,适用于 PHP-PCRE、Python、GO、JavaScript、Java、C#-.NET、Rust 等语言。

image-20240513233300327

4.2 RegExr

地址:regexr-cn.com

带有语法高亮、支持 PHP/PCRE 和 JS 语言、上下文解释、备忘单、参考和正则表达式社区的正则表达式测试工具。

image-20240513233809937

4.3 GoRegex

地址:goregex.cn

提供PHP、PCRE、Python、Go、JavaScript等语言的正则表达式在线测试、生成,解析工具服务。其中的正则库及正则教程可以帮助快速方便的获取正则表达式。

image-20240513234042057

4.4 RegexLearn

地址:regexlearn.com/zh-cn

交互式学习正则表达式,在所处的阶段练习、测试和分享自己的正则表达式。

image-20240513234207157

玩转npm:从基础到实践的全面指南

1 简介

npm(Node Package Manager)是Node.js生态系统中的默认包管理器,它提供了一系列的命令行工具,使得开发者能够方便地进行包的管理操作。这些操作包括但不限于下载、安装、升级、删除包,以及发布和维护自己的包。

以下是npm的一些主要功能:

  • 包管理:通过npm install命令安装项目所需的包,并将其添加到项目的依赖中,减少重复劳动。
  • 版本管理:指定项目依赖项的版本,确保项目不受不兼容版本的影响。
  • 脚本执行:在package.json文件中定义脚本,使用npm run命令执行。
  • 包发布和分享:开发者可以将自己编写的包发布到NPM的公共仓库中,供其他开发者使用。
  • 依赖解析:递归地解析和安装其依赖项,确保项目中的所有依赖都得到满足。
  • 包搜索和浏览:在NPM网站上搜索、浏览和发现其他人创建的包。

2 安装NPM

npm不需要单独的安装,在安装Node.js的时候会相应的安装npm。

  1. 前往Node.js官网下载并安装最新版本Node.js

image-20240425225114401

  1. 验证npm是否安装成功
1
2
npm -v    # 查看npm版本,若输出版本号,即为安装成功
# 10.5.1

3 基本使用

初次运行npm时,可以使用npm init命令进行初始化操作,它会引导填写一些基本信息(如版本号、描述等)

image-20240425230442939

初始化项目后创建package.json文件

package.json文件

package.json文件通常用来描述项目和软件包信息。

  • name:项目或库的名称
  • version:项目的版本
  • author:项目作者
  • description:项目的描述
  • license:项目的许可证

scripts

scripts字段用于定义项目中的各种脚本命令。可以在其中指定一些常用的操作,比如启动项目、执行测试、构建等,并且可以通过命令行工具来执行这些脚本。

例如,假设想在每次提交代码前运行测试,可以创建一个名为precommit的脚本:

1
2
3
4
5
6
{
"scripts": {
"prestart": "npm install",
"start": "node index.js"
}
}

在命令行使用npm run prestart等同于执行npm install

每个script都是一个命令行指令,后面跟着要执行的具体命令。当开发者克隆一个仓库并在自己的机器上运行npm installyarn安装依赖后,可以通过npm run <scriptName>yarn <scriptName>来执行这些预设的任务。这样的自动化大大提高了开发效率,减少了重复劳动,并且确保所有开发者和CI/CD流水线都能以相同的方式执行相同的步骤。

dependencies和devDependencies

dependencies和devDependencies是项目配置文件中的两个重要部分,它们用于分别列出项目运行时和开发时所需的外部模块或库。

  • dependencies:项目在实际运行时所依赖的模块或库。这些依赖项是在生产环境中必须安装和包含的包,因为它们包含了项目功能实现的核心代码或是该应用程序直接使用的库。当用户全局安装该应用程序或在系统上运行它时,npm会自动将这些依赖项下载并安装到node_modules目录中。
  • devDependencies:项目在开发过程中所需要的工具、测试框架、构建工具等,它们通常不参与项目的实际运行。这包括测试库、构建脚本、代码格式化工具等。当发布应用程序时这些依赖项不会被包含在内,但是其他开发者如果要在本地开发或测试代码,则需要安装这些依赖项。

在package.json中明确指定这些依赖项,可以确保任何人在新的环境中克隆和设置项目时都能够获得正确的版本,并且能够重现构建过程。这对于团队协作和持续集成/持续部署(CI/CD)流程至关重要。

4 常用命令

npm提供了许多有用的命令来帮助管理项目的依赖项和其他相关任务。下面是一些最常用的npm命令:

  1. npm init:初始化一个新的Node.js项目,创建一个package.json文件。
  2. npm install:安装所有依赖项以及未列出的新依赖项。
    • npm install :安装一个新依赖项到你的项目。
    • npm install --save:安装一个依赖项,并将其添加到dependencies中。
    • npm install --save-dev:安装一个开发依赖项,并将其添加到devDependencies中。
  3. npm uninstall :卸载一个依赖项。
  4. npm update:更新所有过期的依赖项到最新版本。
  5. npm outdated:列出所有过期的依赖项。
  6. npm ls:显示已安装的包及其版本信息。
  7. npm publish:发布你的包到npm仓库。

更多npm命令可参阅CLI 命令 | npm 中文网 (nodejs.cn)

5 全局安装与本地安装

在 npm 中,可以选择全局安装或本地安装包。这两种方式各有用途:

  • 全局安装 (npm install -g):全局安装的包对所有项目都可用。这意味着无论在哪里,都可以在命令行中访问这些包。这适用于那些不打算在单个项目中使用,而是希望在整个系统范围内使用的工具或命令行程序。例如,如果你经常需要使用某个代码格式化工具或构建脚本,全局安装可以让它在任何地方都可以使用。
  • 本地安装 (npm install):本地安装的包仅限于当前项目的node_modules目录。这意味着其他项目不能访问这些包,除非也为它们安装了同样的依赖项。这适用于那些项目直接依赖的库或工具。例如,如果你的项目需要一个特定版本的jQuery,你应该本地安装它,因为它只对你当前的项目有用。

image-20240428000553721

一般来说,建议尽可能使用本地安装,因为它允许精确控制每个项目的依赖关系,并且避免不同项目之间的冲突。全局安装主要用于那些你需要在多个项目间共享的工具或命令行实用程序。

6 版本管理和兼容性策略

npm版本管理和兼容性策略是确保项目顺利运行的关键部分。以下是一些建议:

  1. 使用语义化版本控制:遵循语义化版本控制规则,即主版本号.次版本号.修订号。当发布新功能时,增加次版本号;当修复 bug 时,增加修订号;当做出破坏性更改时,增加主版本号。这有助于开发者了解他们是否需要升级他们的代码以适应新版本。
  2. 锁定文件:使用package-lock.json或yarn.lock文件来锁定依赖项的具体版本。这可以防止因不同版本而导致的问题,并确保在不同环境中具有相同的一致性和可预测性。
  3. 定期更新:定期运行npm update来更新依赖项到最新版本,以利用最新的改进和安全修复。但请小心重大更新,因为它们可能会引入不兼容的变化。
  4. 依赖项兼容性:当添加新依赖项时,尽量选择广泛支持和积极维护的包。
  5. 测试:在更新依赖项之前,最好在一个隔离的环境中测试它们,比如使用Docker或虚拟机,以确保它们不会破坏现有的功能。
  6. 回退计划:如果更新导致问题,确保有一个回退计划。这可能意味着保留旧版本的代码或依赖项,直到问题解决。
  7. 监控:监控项目以识别潜在的安全漏洞和性能问题。有许多工具和服务可以帮助做到这一点,包括Snyk、Greenkeeper等。
  8. 文档:及时更新README.md或其他文档,说明项目依赖哪些版本的包,以及如何安装和配置它们。

通过遵循这些实践,可以最大限度地减少因依赖项更新而引起的问题,并确保项目稳定可靠。

package-lock.json文件:

package-lock.json文件是npm在执行npm install命令后自动生成的一个锁文件,其目的是确保在不同环境下能够一致地安装相同版本的依赖项。这个文件描述了项目所需的每个依赖的确切版本号以及解析后的实际下载地址。

7 案例分析:创建一个简单的npm模块并发布

  1. 确定模块名称

在GitHub或其他代码托管服务上检查模块名称是否可用,确保该名称没有被其他npm包占用。

  1. 初始化模块

在开发目录中创建一个新的文件夹作为模块项目,在该文件夹内运行npm init命令初始化package.json文件,它会引导填写一些基本信息(如版本号、描述等),或者使用npm init -y命令快速初始化。

image-20240427230309324

  1. 编写代码

在项目目录中创建一个JavaScript文件,通常命名为index.js,在其中编写模块代码,并且确保它能作为一个Node.js模块正确导出功能或类。

  1. 编辑package.json文件

添加必要的元数据,包括模块的名称、版本号、描述、作者、许可证等,如果需要,还可以添加 scripts 部分来自定义命令,例如启动脚本或测试脚本。

  1. 发布模块

第一次发布需要先注册一个npm账户

1
2
# 注册账户
npm adduser

image-20240428001100253

如果有npm账户则直接登录

1
2
# 登录账户
npm login

最后使用npm publish命令将模块发布到npm仓库

  1. 后期维护

对于每次更新,需要先递增版本号,然后再次运行npm publish来更新已发布的模块版本。

8 总结

总的来说,npm不仅是Node.js的核心组成部分,也是现代前端工程化的基石。掌握npm意味着掌握了JavaScript开发的未来趋势,它是每个前端工程师必备的基本功。随着Node.js及JavaScript技术的不断演进,相信npm将继续发挥其重要作用,引领着Web开发的新潮流。

值得推荐的7个vue3 UI组件库

前端 UI 组件库是前端开发者必备的工具之一,它们可以帮助开发者快速构建用户界面,提高开发效率。本文推荐几款热门的vue3 UI组件库,排名不分前后。

Naive UI

开发团队:TuSimple(图森未来)

官网:www.naiveui.com/

GitHub:github.com/tusen-ai/naive-ui/

Naive UI是由TuSimple团队开发并维护的一个现代化的Vue 3组件库。它旨在提供一套简洁、直观且易于使用的界面元素,帮助开发者快速构建美观的应用程序。Naive UI提供了包括按钮、输入框、布局、表格、提示等在内的多种常见UI组件,这些组件都遵循Material Design设计规范,以确保一致的视觉效果和用户体验。

image-20240409221834250

  • **TypeScript支持:**为开发者提供了丰富的类型定义,有助于在编码阶段捕获潜在错误,提升开发效率和代码质量。
  • **强大的主题系统:**通过简单的JSON配置,就可以改变全局颜色、字体等样式,甚至可以创建暗黑模式,极大地减少了前端开发者的工作负担。
  • **应用场景广泛:**适用于各类Web应用程序的开发,无论是要构建企业级后台管理平台,还是要设计简洁的个人博客,或者是开发移动优先的响应式网站,都能找到合适的组件。
  • **易用性强:**清晰的API接口和详尽的文档说明,使得学习和使用它非常容易。
  • **响应式设计:**所有组件均支持响应式布局,适应不同设备和屏幕尺寸。

总的来说,Naive UI是一个功能强大、易于使用的Vue 3组件库,适合于各种规模的项目的开发,成为了许多开发者构建现代Web应用程序的首选组件库。

安装

1
2
# NPM
npm i -D naive-ui

Element+

开发团队:饿了么前端

官网:element-plus.org/

GitHub:github.com/ElemeFE/element/

Element+,也被称为Element Plus,是一个基于Vue 3.x的前端界面框架,它提供了一套丰富的UI组件库,旨在帮助开发者快速构建现代化的用户界面。Element Plus是Element UI的升级版,Element UI是基于Vue 2.x的界面框架,而Element Plus则基于Vue 3.x。

image-20240409225831748

  • 丰富的组件库:Element Plus提供了一系列常用的UI组件,如按钮、表单、弹窗、导航等,可以帮助开发者快速构建现代化的用户界面。
  • 简洁易用:Element Plus的设计理念是简洁、易用和美观,它遵循了Material Design的设计原则,采用了扁平化的风格和鲜明的色彩搭配,给用户带来了良好的视觉体验。
  • 高效的开发流程:Element Plus将HTML的基础控件进行了封装,用户只需要调用这些控件就可以了,而不需要用CSS去调整风格。

总的来说,Element Plus是一个非常强大且易于使用的UI框架,它可以帮助开发者快速构建出高质量的应用程序。

安装

1
2
3
4
5
6
7
8
# NPM
npm install element-plus --save

# Yarn
yarn add element-plus

# pnpm
pnpm install element-plus

Quasar

开发团队:Quasar团队

官网:quasar.dev/ (中文网:http://www.quasarchs.com/

GitHub:github.com/quasarframework/quasar/

Quasar是一个基于Vue.js的开源前端框架,它允许开发者仅编写一次代码,然后就可以将应用部署到多个平台上,如网站、渐进式网页应用(PWA)、移动应用和Electron应用。Quasar的设计理念是简化开发流程,提高开发效率,并确保应用的性能和质量。

image-20240411135059881

  • 跨平台开发:Quasar 使开发者只需编写一次代码,即可跨多个平台无缝部署,包括 Web、移动、桌面和 Electron。这种统一的开发方案简化了开发工作流程,并确保不同设备和环境下一致的用户体验。
  • 大型组件库:Quasar 拥有超过 70 个高性能 Material Design 组件的库,为开发者提供了丰富的工具包,用于构建响应灵敏且具有视觉吸引力的 App。这些组件完全可定制,允许开发者对其进行定制,满足特定的设计要求和品牌偏好。
  • 文档齐全的 API:Quasar 拥有全面且文档齐全的 API,易于学习和使用。这种清晰且结构化的文档简化了开发过程,使开发者能够有效地利用 Quasar 的特性和功能。
  • 繁荣的社区:在大型活跃的开发者社区的支持下,Quasar 促进协作、知识共享和支持。无论是寻求帮助、分享见解还是为框架的发展开源贡献,开发者都可以依赖 Quasar 社区的指导和友情赞助。
  • 开源:作为一个开源框架,Quasar 可以免费使用和修改,开发者能够为所欲为地创新和定制它们的 App。这种开放的精神鼓励 Quasar 生态系统的透明度、社区参与和持续改进。

总的来说,Quasar是一个功能强大的前端框架,它可以帮助开发者更快地构建出高质量的应用,并且支持多种不同的平台和应用类型。

安装

1
2
3
4
5
6
7
8
9
10
11
# NPM
npm i -g @quasar/cli
npm init quasar

# Yarn
yarn global add @quasar/cli
yarn create quasar

# pnpm
pnpm add -g @quasar/cli
pnpm create quasar

Vuetify

开发团队:Vuetify(公司)

官网:vuetifyjs.com/

GitHub:github.com/vuetifyjs/vuetify/

Vuetify 广泛的精心设计的 UI 组件、布局和主题与谷歌的 Material Design 原则无缝衔接。开发者即使没有丰富的设计专业知识,也能够构建具有专业才能的、精美且响应灵敏的 Web App。

image-20240411135110831

  • 丰富的组件集:Vuetify 拥有广泛的 80 多个预构建 UI 组件。从按钮和表单等基本元素,到数据表和导航抽屉等复杂结构,Vuetify 涵盖了广泛的 UI 需求。
  • 响应式设计:Vuetify 中的每个组件都经过精心设计,具有本质上的响应性。这可确保使用 Vuetify 构建的 App 在从 PC 端到移动端的各种设备上保持视觉完整性。
  • 主题:Vuetify 提供强大的主题功能,开发者能够轻松定制其 App 的视觉美感。无论是创建定制主题,还是利用大量预构建选项,Vuetify 都使开发者能够定制 App 的外观和风格,满足特定偏好或品牌要求。
  • 国际化:凭借对国际化的内置支持,Vuetify 简化了创建迎合全球受众的 App 的过程。开发者可以无缝实现多语言支持和本地化功能,确保它们的 App 在全球范围内均可访问且用户友好。
  • 元气满满的社区:Vuetify 因其元气满满且积极参与的开发者社区而蓬勃发展。凭借庞大且支持的用户群,开发者可以轻松访问资源、寻求帮助,并与志同道合的个人协作。Vuetify 的社区驱动精神营造了持续学习和创新的环境。

总的来说,Vuetify是一个非常强大的前端框架,它可以帮助开发者快速构建出既美观又实用的Web应用程序。

安装

1
2
3
4
5
6
7
8
# NPM
npm create vuetify@latest

# Yarn
yarn create vuetify

# pnpm
pnpm create vuetify

Varlet

开发团队:varletjs社区

官网:varlet.gitee.io/varlet-ui/

GitHub:github.com/haoziqaq/varlet/

Varlet是一个基于Vue3开发的Material风格移动端组件库,全面拥抱Vue3生态,追求轻量的组件体积,简单的使用方式,最小的思维负担。Varlet提供了60多个高质量通用组件,旨在帮助开发者更高效地构建移动端应用。

image-20240418205745060

  • 轻量级:Varlet致力于保持组件的轻量化,以方便开发者更容易地管理和维护。
  • 易于使用:Varlet的使用方式简单,减少了开发者的思维负担,使他们能够更专注于业务逻辑的实现。
  • 丰富的组件库:Varlet提供了60多个高质量通用组件,覆盖了大部分常见的界面元素和交互行为,大大提高了开发效率。
  • 支持按需引入:Varlet支持按需引入,这意味着可以根据项目的实际需求来选择需要的组件,从而减少不必要的代码加载,提高应用的性能。
  • 支持国际化:Varlet支持国际化,无论在哪个国家或地区,都可以使用Varlet来开发应用。

总的来说,Varlet的使用场景广泛,适用于各种类型的移动端应用开发。如果需要一个强大的、易用的、轻量级的移动端组件库,那么Varlet或许是一个不错的选择。

安装

1
2
3
4
5
6
7
8
# NPM
npm i @varlet/ui -S

# Yarn
yarn add @varlet/ui

# pnpm
pnpm add @varlet/ui

PrimeVue

开发团队:PrimeTek

官网:v4.primevue.org/

GitHub:github.com/primefaces/primevue/

PrimeVue是一个基于Vue.js的UI组件库,它提供了丰富的、灵活的和现代的UI组件,旨在帮助开发者构建功能强大的Web应用程序。PrimeVue提供了一系列的组件,包括表单元素、数据表格、图表、日历等。这些组件支持响应式设计,能够在不同尺寸的屏幕和设备上提供良好的视觉效果。

image-20240418211307209

  • 丰富的组件集:PrimeVue提供了多样化的组件,包括按钮、输入框、数据表、图表等,满足了开发者在构建用户界面时的各种需求。
  • 主题自定义:PrimeVue允许开发者根据项目的需求定制主题,从而使UI更符合特定设计要求。
  • 灵活性和可定制性:组件库提供了很大的灵活性和可定制性,使得开发者能够根据项目需求进行个性化定制。
  • 社区支持:PrimeVue有一个积极的社区,用户可以在论坛上获取支持、提出问题,并分享经验。
  • 响应式设计:PrimeVue提供了对现代响应式设计的支持,使得应用能够适应各种设备和屏幕尺寸。

总的来说,PrimeVue是一个不断发展的Vue组件库,它提供了广泛的组件和灵活的定制选项,适合各种规模的Web应用程序开发。随着最近的更新,PrimeVue的组件集变得更加丰富,为开发者提供了更多的选择来构建现代化、响应式的用户界面。

安装

1
2
3
4
5
6
7
8
# NPM
npm install primevue@4.0.0-beta.1

# Yarn
yarn add primevue@4.0.0-beta.1

# pnpm
pnpm add primevue@4.0.0-beta.1

Buefy

开发团队:Rafael Beraldo(原始作者)

官网:buefy.org/

GitHub:github.com/buefy/buefy/

Buefy是一个基于Vue.js的轻量级UI组件库,它基于Bulma框架和设计。Buefy提供了响应式的UI组件,适合用于构建美观且高效的Web应用。它的组件设计遵循Material Design和iOS的设计原则,能够在不同设备和操作系统上保持一致的用户体验。Buefy的代码结构清晰,易于定制和扩展,支持按需引入,有助于减少项目的体积。

image-20240418212732113

  • 提高开发效率:Buefy提供了丰富的响应式UI组件,使得开发者能够更快地搭建出既符合设计规范又具有良好用户体验的Web应用。
  • 简化开发流程:通过使用Buefy,开发者可以减少重复造轮子的时间,专注于业务逻辑的实现,从而提高整体的开发效率。
  • 提升用户体验:Buefy的组件设计遵循Material Design和iOS的设计原则,能够在不同设备和操作系统上保持一致的用户体验,这对于提升应用的可用性和吸引力至关重要。
  • 支持定制化和扩展性:Buefy的代码结构清晰,易于定制和扩展,这使得开发者可以根据实际需求调整组件行为,满足多变的业务需求。

总的来说,Buefy在大型复杂应用中的表现取决于具体的应用需求和开发者的使用技巧。对于小型到中型项目,Buefy可能是一个理想的轻量级选择。但对于需要更多定制化组件和企业级特性的大型应用,可能需要考虑其他更专业的Vue组件库。

安装

1
2
# NPM
npm install buefy

全面详细的常用Linux命令汇总(1)

无论是Linux的新手还是老手,掌握一些常用命令都是必不可少的,熟练使用它们可以大大提高工作效率,成为工作中的得力助手。本文是常用Linux命令汇总系列文章的第一篇,全面详细的展示了10个与文件管理相关的命令。

一览表

序号命令简述分类
1ls列出目录内容文件管理
2cd切换目录文件管理
3pwd显示当前工作目录的路径文件管理
4mkdir创建新目录文件管理
5cp复制文件或目录文件管理
6mv移动或改名文件文件管理
7touch创建空文件与修改时间戳文件管理
8rm删除文件或目录文件管理
9ln为文件创建快捷方式文件管理
10cat显示文件内容文件管理

1. ls命令

ls命令是英文list的缩写,用于列出指定目录的内容,能够显示文件名、文件类型、文件大小、最后修改时间等信息

语法格式

1
ls [参数] [文件或目录名]

常用参数

1
2
3
4
5
6
7
8
9
ls -a    列出包括隐藏文件的所有文件
ls -A 列出除当前目录(.)和父目录(..)所有文件和目录
ls -d 当遇到目录时列出目录本身而非目录内的文件
ls -i 显示每个文件的索引编号(inode号)
ls -l 显示文件的属性信息,包括权限、所有者、大小、创建时间等
ls -R 递归列出目录中的所有文件和子目录
ls -S 依据内容大小将文件排序显示,最大的在最前
ls -t 按修改时间排序,最新的在最前
ls -X 依据文件扩展名排序

实例

(1)列出/bin目录下的文件

1
ls /bin

image-20240314155802479

(2)按照修改时间列出所有文件的详细信息

1
ls -Alt

image-20240314161027100

(3)结合通配符*使用,显示目录中以a开头的文件列表

1
ls a*

image-20240314164601891

(4)查看当前目录中某一目录的权限

1
ls -ld dir2

image-20240314230031404

注意

  • 对于-a-A参数,ls 命令是区分大小写的

2. cd命令

cd命令是英文change directory的缩写,用于更改当前所处的工作目录,路径可以是绝对路径,也可以是相对路径

语法格式

1
cd 目录名

常用参数&实例

1
2
3
4
5
6
cd /root/dir1/directory    切换到绝对路径
cd dir1/directory 切换到相对路径
cd .. 切换到上级目录
cd ../.. 切换到上上级目录
cd ~ 或 cd 切换到用户主目录
cd - 切换到上次访问的目录

3. pwd命令

pwd命令是英文print working directory的缩写,用于显示当前工作目录的路径,一般不需要配合任何参数去使用

语法格式

1
pwd

实例

显示当前工作目录的路径

1
pwd

image-20240315013440393

4. mkdir命令

mkdir命令是英文make directories的缩写,用于创建目录文件

语法格式

1
mkdir [参数] 目录

常用参数

1
2
3
mkdir -m    创建目录的同时设置权限
mkdir -p 递归创建多级目录
mkdir -v 显示执行过程详细信息

实例

(1)建立一个目录文件

1
mkdir dir3

image-20240314225041763

(2)创建一个新目录并赋予所有者完全权限(读、写、执行),组成员读权限和执行权限,其他用户只读权限

1
mkdir -m 754 dir4

image-20240314230231760

(3)一次性创建多个有嵌套关系的目录文件

1
mkdir -p dir3/dir33/dir333

image-20240314230514736

注意

  • 使用-p参数时,如果目录已经存在,命令不会报错,而是继续执行
  • 如果没有足够的权限或目录已存在,命令会失败

5. cp命令

cp命令是英文copy的缩写,用于复制文件或目录,将一个或多个文件或目录复制到指定位置

语法格式

1
cp [参数] 源文件或目录 目标文件或目录

常用参数

1
2
3
4
5
6
7
8
9
10
cp -a    通常在复制目录时使用,它保留链接、文件属性,并复制目录下的所有内容,功能等同dbR参数
cp -d 复制链接文件时,将目标文件也创建为链接文件而非普通文件,这里链接类似Windows中的快捷方式
cp -f 若目标文件已存在,则会直接覆盖,不会提示用户确认
cp -i 若目标文件已存在,对每个将要覆盖的目标文件都会提示用户确认
cp -l 用于创建硬链接,硬链接是一种指向同一文件的指针,使得多个文件名可以引用相同的数据块
cp -p 复制时保留源文件的权限、所有者和时间戳等属性信息
cp -r 复制目录时递归复制其所有子目录和文件
cp -s 用于创建符号链接(软连接),类似Windows快捷方式,是一个包含链接路径的特殊类型文件
cp -u 仅当源文件比目标文件新,或者目标文件不存在时,才进行复制
cp -v 显示执行过程详细信息

实例

(1)复制源文件到指定目录,并定义新文件的名称

1
cp file1 dir2/new_file

image-20240315004421360

(2)复制指定的源目录,并定义新目录的名称,显示执行过程详细信息

1
cp -rv dir3 dir5

image-20240315003505733

(3)复制指定文件时保留原始属性信息,并强制覆盖已有目录

1
cp -af article.md dir4

image-20240315010344208

注意

可以将一个文件通过复制来覆盖一个已有文件或者复制添加到一个目录中,但无法将一个目录通过复制来覆盖一个已有目录,如果使用cp -r 目录 已有目录命令,会把目录复制添加到已有目录中

6. mv命令

mv命令是英文move的缩写,用于移动文件或目录,与cp复制命令不同,mv命令是剪切操作,只有文件位置发生了变化,而文件总个数并没有增加

语法格式

1
mv [参数] 源文件或目录 目标文件或目录

常用参数

1
2
3
4
5
mv -f    若目标文件已存在,则会直接覆盖,不会提示用户确认
mv -i 若目标文件已存在,对每个将要覆盖的目标文件都会提示用户确认
mv -n 不覆盖已存在的目标文件
mv -u 仅当源文件比目标文件新,或者目标文件不存在时,才进行复制
mv -v 显示执行过程详细信息

实例

(1)移动源文件到指定目录,并定义新文件的名称

1
mv file2 dir1/new_file

image-20240315015109752

(2)重命名当前目录下的文件或目录的名称

1
mv file2 file3

image-20240315021423039

注意

  • mv命令会覆盖文件,为避免误删文件,可以使用-i参数
  • 如果目标文件是一个目录,源文件会被移到此目录下,且文件名不变。如果目标文件不是目录,源文件名会变为目标文件名,并覆盖已存在的同名文件

7. touch命令

touch命令用于创建文件与修改文件或目录的时间属性,若文件存在则修改文件的访问时间和修改时间为当前时间,若文件不存在则创建一个新的空文件

语法格式

1
touch [参数] 文件

常用参数

1
2
3
4
5
touch -a    只修改文件的访问时间
touch -m 只修改文件的修改时间
touch -c 如果文件不存在,不会创建新文件
touch -d 使用字符串(YYYY-MM-DD hh:mm:ss)设定时间与日期,而不是使用当前时间
touch -t 使用时间戳(YYYYMMDDhhmmss)设定时间与日期,而不是使用当前时间

实例

(1)创建出一个指定名称的空文件

1
touch file4

image-20240315222535144

(2)修改指定文件的修改时间

1
touch -md "2024-03-04 05:06:07" file1

image-20240315223428148

(3)使用通配符批量修改多个文件的访问时间,并确保不创建不存在的文件

1
touch -ad "2024-03-04 05:06:07" file*

image-20240315230629852

注意

  • 当使用-d-t参数时,确保提供的时间格式正确
  • 如果提供的文件名包含特殊字符,可能需要用引号包围起来

8. rm命令

rm命令是英文remove的缩写,用于删除文件或目录,这是一个危险的命令,如rm -rf /*会清空系统所有文件且无法恢复

语法格式

1
rm [参数] 文件或目录

常用参数

1
2
3
4
5
rm -d    仅删除无子文件的空目录
rm -f 强制删除文件,不会提示用户确认
rm -i 在删除每个文件之前都会询问用户是否确定
rm -r 递归删除目录及其全部子文件
rm -v 显示执行过程详细信息

实例

(1)强制删除指定目录及其内的全部子文件

1
rm -rf dir1

image-20240317225703255

(2)删除当前目录下的所有文件及目录,并且每个文件删除前询问用户是否确认

1
rm -ri *

image-20240317230457708

(3)删除系统的所有文件(不要尝试!!!)

1
rm -rf /*

注意

  • 谨慎使用rm命令,一般情况下删除的文件或目录无法恢复

9. ln命令

ln命令是英文link的缩写,用于为某个文件在另外一个位置建立同步的链接(硬链接)。Linux系统中的链接文件有硬链接和软链接(符号链接)两种形式,软链接相当于Windows系统中的快捷方式文件,原始文件被移动或删除后软链接文件也将无法使用;硬链接则是将文件的inode属性块进行了复制,因此把原始文件移动或删除后硬链接文件依然可以使用

语法格式

1
ln [参数] 源文件或目录 目标文件或目录

常用参数

1
2
3
4
5
6
7
ln -d    允许超级用户尝试创建指向目录的硬链接
ln -f 若目标文件已存在,则会直接覆盖,不会提示用户确认
ln -i 若目标文件已存在,对每个将要覆盖的目标文件都会提示用户确认
ln -r 根据相对位置创建软链接而非绝对路径
ln -s 创建软链接
ln -t 设置链接文件的存放目录
ln -v 显示执行过程详细信息

实例

(1)创建软链接

1
ln -s file1 file2

image-20240317170238335

(2)创建硬链接,当目标文件存在时询问是否覆盖

1
ln -i file1 file2

image-20240317170756446

注意

  • 目录只能创建软链接
  • 目录创建链接必须用绝对路径,使用相对路径创建会提示:符号连接的层数过多

10. cat命令

cat命令是英文concatenate的缩写,用于在终端设备上打印出文件内容,适合查看内容较少的纯文本文件,对于内容较多的文件查看后会在屏幕上快速滚屏看不清所显示的具体内容

语法格式

1
cat [参数] 文件

常用参数

1
2
3
cat -n    由1开始对所有输出的行数编号
cat -b 和-n相似,但对空白行不编号
cat -s 遇到有连续两行以上的空白行,就换为一行的空白行

实例

(1)查看指定文件的内容并显示行号

1
cat -n file1

image-20240320163041761

(2)把文件A的非空白行内容加上行号,之后将其附加到文件B中

1
cat -b file2 >> file3

image-20240320165734429

注意

  • cat命令默认会一次显示整个文件,如果文件过大可能会导致终端卡顿
  • cat命令可以用来创建新的空文件,但不能编辑文件

了解USB接口的类型与特点

1 前言

在当今数字时代,无论是连接电脑、手机、平板还是其他各种外设,USB接口都发挥着重要作用,但USB接口类型和外观多样,导致出现很多错误叫法,像什么“华为口”、“安卓口”等,实际上每一款USB接口及其变体都有名称,每种类型也都具有其独特的特点和用途。

注意

本文部分内容和数据参考 USB-IF,如需更深入详细的研究,建议前往其官网查看

2 关于USB接口

2.1 USB接口的定义

USB(Universal Serial Bus)中文名称为通用串行总线,是一种快速同步传输的双向串行接口标准,用于规范电脑、移动设备等与外部设备的连接和通讯,由英特尔、微软等几家公司联合成立USB-IF组织并研发和制定了USB传输协议。USB在手机、电脑、鼠标、键盘、摄影器材、电视机、游戏机、充电器、磁盘等设备中得到广泛应用,并支持各种操作系统(windows、MAC、Linux 等)。截止2023年,USB标准版本已历经4代大版本发展,凭借使用便捷、速度快、可扩展性强的特性,USB已经成为消费者的设备连接首选

image-20240305231948900

2.2 USB接口的特点

通用兼容性:USB 接口被广泛应用于各种设备,如电脑、手机、平板、外部存储设备、打印机等,具有很好的通用性。

热插拔功能:你可以在不关闭设备电源的情况下插拔 USB 设备,非常方便。

传输速度:USB 接口的传输速度不断提升,从早期的 USB 1.0 到现在的 USB 3.0、USB 4.0 等,满足了不同设备对数据传输速度的需求。

可扩展性:一个 USB 接口可以通过集线器连接多个 USB 设备,扩展了设备的连接能力。

供电功能:USB 接口可以为一些设备提供电力,方便了设备的使用,减少对额外电源的需求。

成本相对较低:USB 接口的制造成本相对较低,使得它在各种设备中得到广泛采用。

数据传输稳定:USB 接口采用差分信号传输,能够有效地减少干扰,保证数据传输的稳定性。

image-20240305181912852

3 USB接口的分类

3.1 大分类

根据USB-IF组织提出的串口总线标准,USB连接器分为A、B两种,A用于主机、B用于设备,Standard是标准接口,Mini是小型接口,Micro是微型接口,但Type-C只有一种外形的接口,并且未来USB接口将会逐步统一到Type-C接口上

image-20240305234636338

3.2 按外观

USB根据外观和大小,大致可以分为三种,分别为Type、Mini和Micro

image-20240305180414000

3.3 按版本

随着科技发展和技术进步,USB接口也随着时代进行版本更替,由最初的USB 1.0到现在的USB4,传输速度完成了从1.5Mbps到40Gbps的飞跃

image-20240306000853663

USB接口的版本由于一些原因经历过多次修改名称,导致现在各版本区分混乱,网络上也出现了少数商家通过版本漏洞来销售商品,比如一款U盘,介绍为USB 3.2,实际版本为USB 3.2 Gen1,也就是曾经的USB 3.0,速度相差了至少5Gbps

image-20240306003439443

4 深入了解不同USB接口

4.1 Type-A

Type-A接口绝对是USB中最经典的一款接口,实际上除了标准版本还有Mini、Micro等版本,不过已经成为被时代淘汰的产品了,现在也很难看到他们的影子

标准Type-A

一般标准的Type-A接口可以通过颜色分辨版本,USB 2.0为白色,USB 3.0为蓝色,但还是通过金属触点数量区分USB 3.0和USB 2.0更靠谱

  • USB 2.0 4金属触点
  • USB 3.0 9金属触点

image-20240306144938017

Type-A也有一些局限性,与较新的接口类型相比,它的传输速度较慢并且尺寸较大,但它普及广泛这是不可否认的,大多数电脑和设备都支持Type-A接口,所以在连接设备时非常方便

4.2 Type-B

标准Type-B

Type-B接口常用于大型设备,如打印机、扫描仪等,它在USB 2.0和USB 3.0两个版本的外观出现了变化,在USB 2.0的基础上,USB 3.0在上方凸起了一块,并新增了五个触点

  • USB 2.0 4金属触点
  • USB 3.0 9金属触点(可兼容2.0)

image-20240307010819680

Mini Type-B

Mini-B接口常用于老式功能机,如老式MP3和早期非智能手机等,它也是被淘汰的产品,没有出现USB 3.0版本,USB 2.0的它和Type-B一样,仅有四个触点

Micro Type-B

Micro-B 2.0接口常用于老式安卓手机,因此以前总是被叫做“安卓口”,它有五个金属触点,USB 3.0版本的接口虽然和2.0版本同为Micro-B,但外观形状发生了变化,也没有被广泛用在手机上,而是在移动硬盘等设备上使用的更多,金属触点由五个增加到了十个

  • USB 2.0
  • USB 3.0

image-20240307144228450

4.3 Type-C

因为Type-A/Type-B的接口太落后,而人们想要一款体积小巧、支持正反插、充电和数据传输都更快、功能更加强大的接口,所以Type-C出现了,曾经也被人们叫做“华为口”

image-20240307144455109

  1. 更小巧

它的体积仅为8.3mm×2.5mm,要远远小于Type-A和Type-B的产品

  1. 更方便

支持正反插,可以承受一万次以上的反复拔插,能力远好于Micro-B,能够实现一根线解决所有问题

image-20240307150815496

  1. 更强大

有更好的物理承载能力和协议兼容性,24个金属触点,兼容USB2.0、USB3.0、USB4、雷电3/4协议,也是唯一支持USB4协议的接口

  1. 其他

最高40Gbps带宽,最高100W供电,笔记本拥有外接8K显示器的能力

image-20240307150819799

5 拓展阅读

5.1 USB4协议

USB4协议下的接口有半速USB4 20Gpbs全速USB4 40Gbps两种,需要注意的是,自USB4后对协议的命名方式发生了改变,USB4前的命名方式为USB +x.x(版本号) +GenY(第几代,Y为代数) +×2(部分版本速度翻倍则乘二),USB4后的命名方式为USB4 +速度(Gbps),直接以速度来标明具体版本,避免了名称混乱,在USB和4之间的空格也取消了

image-20240307153034766

USB4(40Gbps)协议特点

1、更快的双通道传输速度,最高可以拥有40Gbps带宽,还可以外接显卡
image-20240307175809136
2、更强的供电能力
image-20240307175821633
3、更方便的兼容性
image-20240307175830213

5.2 雷电接口

雷电协议的知名度,相对USB协议并没有那么高,它由英特尔与苹果公司联合推出,所以苹果电脑用户相信对雷电协议并不陌生,通常苹果电脑上的Type-C接口,采用的便是雷电协议

image-20240307181428400

2015年雷电3推出,带来了很多超前的特性,譬如高达40Gbps的传输宽带,而同时期的最新USB标准为USB 3.1,传输带宽为10Gbps,但是雷电协议需要独立芯片及英特尔认证,导致使用雷电接口的笔记本价格比较昂贵

image-20240307180647636

值得一提的是,雷电3接口使用了Type-C,发布于2019年的USB4标准是基于雷电3的底层技术所打造的,因此二者也拥有完全相同的传输带宽,并且在兼容性方面几乎完全一致

功能雷电4雷电3USB4
带宽40Gbps20/40Gbps20/40Gbps
带宽动态分配支持不支持支持
外接显卡支持支持支持
强制开启DMA保护没有没有
强制保留充电功能没有没有
支持DP视频协议DP 1.4DP 1.2可选DP 1.4
支持PD快充协议PD 3.0PD 3.0PD 3.0
反向供电最小功率15W15W7.5W
相互兼容性兼容兼容兼容

2023年最新推出的雷电5的带宽达到了80Gbps,它基于行业标准(包括 USB4 V2)构建,将与之前版本的 Thunderbolt 和 USB 广泛兼容

6 写在最后

USB是一种非常重要的接口标准,它为生活带来了很多便利,但是各种各样的版本和名称让人感到复杂,本文就针对这一点问题进行了比较全面的讲解,又以形状和版本为核心分别介绍每一种USB接口。现在已经有很多传统接口被淘汰,未来更是Type-C逐渐代替大部分接口的趋势,希望一线万用的时代快点到来。

❌