爬虫实战1.6.1 了解零宽断言

本文转载:静觅 » 正则表达式中零宽断言的用法

了解了正则表达式,想必一般情况下的匹配都不会出现什么问题,但是如果一些特殊情况,可能需要用到一些更高级的正则表达式匹配操作,本节我们来说明一下正则表达式的一个较常用又比较重要的知识点——零宽断言。

实例引入

首先我们来看一个例子,这里有一段问答对话:

问:我用的是Windows XP+Service Pack 2,为什么无法安装输入卡号和密码的控件? 答:在Windows XP+Service Pack 2、Windows 2003等操作系统中,用户可以自己选择是否安装控件。 问:为什么我看到的卡号输入框显示为*符号? 答:您的浏览器禁止下载执行ActiveX控件 , 对于这种情况 , 您必须打开浏览器的ActiveX的相关权限。 操作方法:在浏览器菜单中选择“工具”|“Internet选项”,在弹出的对话框中选择”安全” |”Internet”|”自定义级别”,在弹出的对话框中选择”重置为 安全级-中” , 点”重置”按钮,确定。 问:看了以上几个问题,还是不能登录,怎么办? 答:您的浏览器由于其他原因不能安装招商银行登录控件, 请下载并安装招商银行登录控件下载版。 问:无法出现个人网上银行大众版登录界面。 答:这种情况是由于您的机器无法和我行服务器建立安全连接,通常是因为代理服务器设置错误引起。如果您是拨号上网,请不要使用代理服务器;如果您过去安装过我行SSL安全代理,请调用“添加-删除程序”删除SSL安全代理;如果您是经过代理访问Internet,请联系您所在网的网络管理员设置代理服务器。IE5.0浏览器设置代理服务器的步骤: Internet选项–>连接–>局域网设置–>使用代理服务器–>高级。 问:我在输入账号和卡号时,总出错,该怎样输? 答:存折账号为10位,按存折本上的账号输入, 密码为6位。如果一卡通是12位卡号的,只需输入地区码后面的8位卡号,不需要输入前面4位的地区码,密码为6位。如果一卡通是16位卡号的,请将16位卡号全部输入,密码为6位。 问:我的存折没有设密码,怎样在个人网上银行大众版中查询余额? 答:存折必须设有密码方可在 个人网上银行大众版 中查询,因此请您到存折开户行给您的存折设置密码。 注:网上个人银行是招商银行为个人客户提供的网上银行。 本页面内容仅供参考,部分业务以当地网点的公告与具体规定为准。

我们需要将这段对话中的问题和答案对提取出来,即提取出如下内容:

Q:我用的是Windows XP+Service Pack 2,为什么无法安装输入卡号和密码的控件?
A:在Windows XP+Service Pack 2、Windows 2003等操作系统中,用户可以自己选择是否安装控件。
Q:为什么我看到的卡号输入框显示为*符号?
A:您的浏览器禁止下载执行ActiveX控件 , 对于这种情况 , 您必须打开浏览器的ActiveX的相关权限。 操作方法:在浏览器菜单中选择“工具”|“Internet选项”,在弹出的对话框中选择”安全” |”Internet”|”自定义级别”,在弹出的对话框中选择”重置为 安全级-中” , 点”重置”按钮,确定。

如果要用 Python实现的话,那么我们很可能自然而然想到split()findall()方法,如果用 split()方法,我们可能会这么写:

import re
results = re.split('问:| 答:', text)
for index, result in enumerate(results[1:]):
    print(('Q' if index%2 == 0 else 'A') + ': ' + result)

这里 split() 方法的第一个参数传入了问:| 答: 这个正则表达式,意思是将这段话用问: 或者 答: 分开,这个功能是正则表达式对字符串进行分割的方法,相比直接字符串的 split()方法功能更为强大。这里其实得到的结果是一个列表,长度是一个奇数,如果我们把 results打印出来,结果是这样的:

['', '我用的是Windows XP+Service Pack 2,为什么无法安装输入卡号和密码的控件?', '在Windows XP+Service Pack 2、Windows 2003等操作系统中,用户可以自己选择是否安装控件。 ', '为什么我看到的卡号输入框显示为*符号?', '您的浏览器禁止下载执行ActiveX控件 , 对于这种情况 , 您必须打开浏览器的ActiveX的相关权限。 操作方法:在浏览器菜单中选择“工具”|“Internet选项”,在弹出的对话框中选择"安全" |"Internet"|"自定义级别",在弹出的对话框中选择"重置为 安全级-中" , 点"重置"按钮,确定。 ', '看了以上几个问题,还是不能登录,怎么办?', '您的浏览器由于其他原因不能安装招商银行登录控件, 请下载并安装招商银行登录控件下载版。 ', '无法出现个人网上银行大众版登录界面。', '这种情况是由于您的机器无法和我行服务器建立安全连接,通常是因为代理服务器设置错误引起。如果您是拨号上网,请不要使用代理服务器;如果您过去安装过我行SSL安全代理,请调用“添加-删除程序”删除SSL安全代理;如果您是经过代理访问Internet,请联系您所在网的网络管理员设置代理服务器。IE5.0浏览器设置代理服务器的步骤: Internet选项-->连接-->局域网设置-->使用代理服务器-->高级。 ', '我在输入账号和卡号时,总出错,该怎样输?', '存折账号为10位,按存折本上的账号输入, 密码为6位。如果一卡通是12位卡号的,只需输入地区码后面的8位卡号,不需要输入前面4位的地区码,密码为6位。如果一卡通是16位卡号的,请将16位卡号全部输入,密码为6位。 ', '我的存折没有设密码,怎样在个人网上银行大众版中查询余额?', '存折必须设有密码方可在 个人网上银行大众版 中查询,因此请您到存折开户行给您的存折设置密码。 注:网上个人银行是招商银行为个人客户提供的网上银行。 本页面内容仅供参考,部分业务以当地网点的公告与具体规定为准。 ']

这是因为我们分割使用的字符本身就处于整个文本的字符,所以一上来就找到了分割的标志 问:,所以它左侧的结果就是空字符串了,所以最终得到的结果第一个内容就是空字符串,后续的内容便是正常的一问一答的短句。所以这里我们还需要对结果进行切片操作,去除第一个元素,然后将其遍历打印输出,最终结果如下:

Q: 我用的是Windows XP+Service Pack 2,为什么无法安装输入卡号和密码的控件?
A: 在Windows XP+Service Pack 2、Windows 2003等操作系统中,用户可以自己选择是否安装控件。
Q: 为什么我看到的卡号输入框显示为*符号?
A: 您的浏览器禁止下载执行ActiveX控件 , 对于这种情况 , 您必须打开浏览器的ActiveX的相关权限。 操作方法:在浏览器菜单中选择“工具”|“Internet选项”,在弹出的对话框中选择"安全" |"Internet"|"自定义级别",在弹出的对话框中选择"重置为 安全级-中" , 点"重置"按钮,确定。
Q: 看了以上几个问题,还是不能登录,怎么办?
A: 您的浏览器由于其他原因不能安装招商银行登录控件, 请下载并安装招商银行登录控件下载版。
Q: 无法出现个人网上银行大众版登录界面。
A: 这种情况是由于您的机器无法和我行服务器建立安全连接,通常是因为代理服务器设置错误引起。如果您是拨号上网,请不要使用代理服务器;如果您过去安装过我行SSL安全代理,请调用“添加-删除程序”删除SSL安全代理;如果您是经过代理访问Internet,请联系您所在网的网络管理员设置代理服务器。IE5.0浏览器设置代理服务器的步骤: Internet选项-->连接-->局域网设置-->使用代理服务器-->高级。
Q: 我在输入账号和卡号时,总出错,该怎样输?
A: 存折账号为10位,按存折本上的账号输入, 密码为6位。如果一卡通是12位卡号的,只需输入地区码后面的8位卡号,不需要输入前面4位的地区码,密码为6位。如果一卡通是16位卡号的,请将16位卡号全部输入,密码为6位。
Q: 我的存折没有设密码,怎样在个人网上银行大众版中查询余额?
A: 存折必须设有密码方可在 个人网上银行大众版 中查询,因此请您到存折开户行给您的存折设置密码。 注:网上个人银行是招商银行为个人客户提供的网上银行。 本页面内容仅供参考,部分业务以当地网点的公告与具体规定为准。

这样确实没问题,我们可以顺利地提取出来,但是总感觉这个解法并不那么优雅,因为我们这里是将问题和答案的内容都单独切出来了,并没有将问答对一块提取,而且 split() 方法返回的结果的第一个元素还不是我们想要的结果,所以还需要进行一些切片操作来去除,所以整个写法感觉实现起来并不完美。

所以我们又想到了 findall()方法,这时我们会这么写:

import re
results = re.findall('问:(.*?) 答:(.*?)', text, re.S)
for result in results:
    print('Q: ' + result[0], 'A: ' + result[1], sep='\n')

表面上看似乎是把问题答案对用正则表示出来了,而且使用了非贪婪匹配,但是很明显,在末尾我们并没有指定匹配的终点,所以整个的结果就会导致回答是完全匹配不到的,运行结果如下:

Q: 我用的是Windows XP+Service Pack 2,为什么无法安装输入卡号和密码的控件?
A:
Q: 为什么我看到的卡号输入框显示为*符号?
A:
Q: 看了以上几个问题,还是不能登录,怎么办?
A:
Q: 无法出现个人网上银行大众版登录界面。
A:
Q: 我在输入账号和卡号时,总出错,该怎样输?
A:
Q: 我的存折没有设密码,怎样在个人网上银行大众版中查询余额?
A:

好,那么我们加上匹配的终点吧,以下一个的问:作为我们正则表达式匹配的终点总可以了吧?所以我们可能会改写成这样子:

import re
results = re.findall('问:(.*?) 答:(.*?)问:', text, re.S)
for result in results:
    print('Q: ' + result[0], 'A: ' + result[1], sep='\n')

这样写似乎看起来是可以了,但结果却是这样的:

Q: 我用的是Windows XP+Service Pack 2,为什么无法安装输入卡号和密码的控件?
A: 在Windows XP+Service Pack 2、Windows 2003等操作系统中,用户可以自己选择是否安装控件。
Q: 看了以上几个问题,还是不能登录,怎么办?
A: 您的浏览器由于其他原因不能安装招商银行登录控件, 请下载并安装招商银行登录控件下载版。
Q: 我在输入账号和卡号时,总出错,该怎样输?
A: 存折账号为10位,按存折本上的账号输入, 密码为6位。如果一卡通是12位卡号的,只需输入地区码后面的8位卡号,不需要输入前面4位的地区码,密码为6位。如果一卡通是16位卡号的,请将16位卡号全部输入,密码为6位。

结果只剩三个问题答案对了,有三个问答对被“吃”掉了,其实这是因为我们的正则表达式最后加了 问:的缘故,findall()方法它会查找所有符合正则表达式的结果,但其中匹配的时候它内部也是有一个查找索引在扫描的。在查找第一个符合要求的结果时,由于我们是根据正则表达式结尾的问:来作为结束标志,所以在找到第一个符合要求的结果时,我们的查找索引就已经移动到了第二个问答对开头的 问:上面,即查找索引就已经进入到了第二个问答对的位置了,而在下一次查找符合要求的结果时,索引会继续往后移动进行扫描,所以它是从第二个问答对的 问:后面继续扫描的,所以对于第二个问答对,实际上已经被割裂了,所以它只能查找到第三个问答对的时候才可以发现符合正则表达式的内容。因此,我们可以观察到,返回的结果只是第一、三、五三个问答对。

所以,如果我们想要用该方法找到完整的留个问答对,就需要用到零宽断言了。

解法如下:

import re
results = re.findall('问:(.*?) 答:(.*?)(?=问:|\Z)', text, re.S)
for result in results:
    print('Q: ' + result[0], 'A: ' + result[1], sep='\n')

运行结果如下:

Q: 我用的是Windows XP+Service Pack 2,为什么无法安装输入卡号和密码的控件?
A: 在Windows XP+Service Pack 2、Windows 2003等操作系统中,用户可以自己选择是否安装控件。
Q: 为什么我看到的卡号输入框显示为*符号?
A: 您的浏览器禁止下载执行ActiveX控件 , 对于这种情况 , 您必须打开浏览器的ActiveX的相关权限。 操作方法:在浏览器菜单中选择“工具”|“Internet选项”,在弹出的对话框中选择"安全" |"Internet"|"自定义级别",在弹出的对话框中选择"重置为 安全级-中" , 点"重置"按钮,确定。
Q: 看了以上几个问题,还是不能登录,怎么办?
A: 您的浏览器由于其他原因不能安装招商银行登录控件, 请下载并安装招商银行登录控件下载版。
Q: 无法出现个人网上银行大众版登录界面。
A: 这种情况是由于您的机器无法和我行服务器建立安全连接,通常是因为代理服务器设置错误引起。如果您是拨号上网,请不要使用代理服务器;如果您过去安装过我行SSL安全代理,请调用“添加-删除程序”删除SSL安全代理;如果您是经过代理访问Internet,请联系您所在网的网络管理员设置代理服务器。IE5.0浏览器设置代理服务器的步骤: Internet选项-->连接-->局域网设置-->使用代理服务器-->高级。
Q: 我在输入账号和卡号时,总出错,该怎样输?
A: 存折账号为10位,按存折本上的账号输入, 密码为6位。如果一卡通是12位卡号的,只需输入地区码后面的8位卡号,不需要输入前面4位的地区码,密码为6位。如果一卡通是16位卡号的,请将16位卡号全部输入,密码为6位。
Q: 我的存折没有设密码,怎样在个人网上银行大众版中查询余额?
A: 存折必须设有密码方可在 个人网上银行大众版 中查询,因此请您到存折开户行给您的存折设置密码。 注:网上个人银行是招商银行为个人客户提供的网上银行。 本页面内容仅供参考,部分业务以当地网点的公告与具体规定为准。

这里我们实际上是使用了(?=)这样的形式来构建了整个表达式,等号后面的内容是 问:或者结束符 \Z,这样其实就保证了在匹配的时候,查找索引不会继续向后移,但这也同时标志了结束标志,因此它就可以查找到完整的内容了。

零宽断言

零宽断言,顾名思义,是一种零宽度的匹配,它匹配的内容不会保存到匹配结果中,表达式的匹配内容只是代表了一个位置而已,如标明某个字符的右边界是怎样的构造。

在前面我们使用了 ?=来进行了实例讲解,这是其中一个用法,另外还有 ?<=、?!、?<!,下面我们来依次进行讲解说明。

  • ?=代表零宽度正预测先行断言,它断言自身出现的位置的后面可以匹配后面跟的表达式。
  • ?<=代表零宽度正回顾后发断言,它断言自身出现的位置的前面可以匹配后面跟的表达式。
  • ?!代表零宽度负预测先行断言,它断言自身出现的位置的后面不可以匹配后面跟的表达式。
  • ?<!代表零宽度负回顾后发断言,它断言自身出现的位置的后面不可以匹配后面跟的表达式。
?=

首先我们来看下 ?=的用法,它断言自身出现的位置的后面可以匹配后面跟的表达式。

比如我们这里有这样的一个字符串:

str = '我的个人邮箱是cqc@cuiqingcai.com,个人博客是cuiqingcai.com,个人公众号是进击的Coder'

在这里我们想把我的个人邮箱这句话和个人邮箱单独摘出来,假如我们不使用零宽断言的话,我们需要给个人邮箱后面这一句加一个结束标识符或者单独匹配邮箱作为标识符,我们可能会这么写:

import re
str = '我的个人邮箱是cqc@cuiqingcai.com,个人博客是cuiqingcai.com,个人公众号是进击的Coder'
result = re.search('我的个人邮箱是(.*?),个人博客', str)
print('整句结果:' + result.group(), '第一个匹配结果:' + result.group(1), sep='\n')

在正则表达式的最后我们加了,个人博客作为匹配的结束符,然后邮箱部分用非贪婪匹配的模式进行匹配,我们看下运行结果:

整句结果:我的个人邮箱是cqc@cuiqingcai.com,个人博客
第一个匹配结果:cqc@cuiqingcai.com

我们可以看到第一个匹配结果成功得到了邮箱信息,但是我们看整句结果缺并不理想,它多匹配了我们加入的结尾标识,并没有得到正常的一句话。

这时候如果我们改用 ?=来匹配,结果就不会带有此标识符了,改写如下:

import re
str = '我的个人邮箱是cqc@cuiqingcai.com,个人博客是cuiqingcai.com,个人公众号是进击的Coder'
result = re.search('我的个人邮箱是(.*?)(?=,个人博客)', str)
print('整句结果:' + result.group(), '第一个匹配结果:' + result.group(1), sep='\n')

在这里我们将结尾标识符改成了(?=,个人博客),这样就将此部分内容作为零宽度匹配,它代表后面需要跟,个人博客,但是它不会出现在匹配结果中。

运行结果如下:

整句结果:我的个人邮箱是cqc@cuiqingcai.com
第一个匹配结果:cqc@cuiqingcai.com

可以看到整句结果中已经没有无用的后缀字符了。

?<=

接下来我们再看下?<=的用法,它代表零宽度正回顾后发断言,其实就是匹配前面的标识,比如这里我们还是以上面的例子为例,匹配出个人博客这句话,代码如下:

import re
str = '我的个人邮箱是cqc@cuiqingcai.com,个人博客是cuiqingcai.com,个人公众号是进击的Coder'
result = re.search('(?<=,)个人博客是(.*?)(?=,)', str)
print('整句结果:' + result.group(), '第一个匹配结果:' + result.group(1), sep='\n')

这里我们在个人博客前面加了一个零宽断言的逗号符号作为开头,使用的就是 ?<=,句子结尾是用的?=,这样前后的标识都不会匹配到了,运行结果如下:

整句结果:个人博客是cuiqingcai.com
第一个匹配结果:cuiqingcai.com

可以看到得到的整句结果也是完整的一句话。

?!

?!代表零宽度负预测先行断言,它断言自身出现的位置的后面不可以匹配后面跟的表达式。也是用来匹配后面的文本,但这里是取反,它指定了后面出现的内容不匹配该标识,我们在前面的例子基础上修改如下:

import re
str = '我的个人邮箱是cqc@cuiqingcai.com,个人博客是cuiqingcai.com,个人公众号是进击的Coder'
result = re.search('我的个人邮箱是(.*?)(?!,个人公众号)(?=,个人博客)', str)
print('整句结果:' + result.group(), '第一个匹配结果:' + result.group(1), sep='\n')

本来是(?=,个人博客)的标识符,不过这里我们使用 ?!来指定了另一个标识符,个人公众号,这就代表这句话后面跟的需要是(?=,个人博客)而不是,个人公众号,运行结果如下:

整句结果:我的个人邮箱是cqc@cuiqingcai.com
第一个匹配结果:cqc@cuiqingcai.com
?<!

?<!代表零宽度负回顾后发断言,它断言自身出现的位置的后面不可以匹配后面跟的表达式。我们在前面的例子基础上加以修改:

import re
str = '我的个人邮箱是cqc@cuiqingcai.com,个人博客是cuiqingcai.com,个人公众号是进击的Coder'
result = re.search('(?<=,)(?<!。)个人博客是(.*?)(?=,)', str)
print('整句结果:' + result.group(), '第一个匹配结果:' + result.group(1), sep='\n')

这里我们写了?<!标识符,后面跟了一个句号,这代表前面不应该出现句号。

运行结果如下:

整句结果:个人博客是cuiqingcai.com
第一个匹配结果:cuiqingcai.com

常用用法

其实上面的示例中我们使用了search()方法进行了内容匹配,其实这并不常用,因为一般我们更关注的是匹配分组结果的内容,其实更多的用法是用在了findall()方法上,它用来匹配多个结果,也就类似于我们一开始的实例一样,这里我们还是以刚才的字符串为例,来输出一下个人邮箱、个人博客、个人公众号三个内容,代码如下:

import re
str = '我的个人邮箱是cqc@cuiqingcai.com,个人博客是cuiqingcai.com,个人公众号是进击的Coder'
results = re.findall('个人(.*?)是(.*?)(?=,|\Z)', str)
for result in results:
    print(result[0] + ': ' + result[1])

这里我们匹配了个人二字,然后后面跟了非贪婪匹配,然后加了一个字,最关键的是结尾标识符,这里必须要使用零宽断言才可以匹配出三个结果,这里匹配的内容是 ,|\Z,意思是匹配逗号或结束符。

运行结果如下:

邮箱: cqc@cuiqingcai.com
博客: cuiqingcai.com
公众号: 进击的Coder

这样我们就成功输出了邮箱、博客及公众号的内容了,匹配非常顺利方便。

结语

通过本节,我们应该大体可以了解了正则表达式中零宽断言的基本用法和适用场景,相信理解了零宽断言之后,我们再做正则匹配时会更加得心应手。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容

  • 在使用正则表达式时,有时我们需要捕获的内容前后必须是特定内容,但又不捕获这些特定内容的时候,零宽断言就起到作用了。...
    EdmundChen阅读 1,488评论 2 2
  • 小心地 趁这几日阳光还明媚的时候 消融内心肮脏的积雪 即使你说 那有你喜欢的冬的气息 你的模样、影子 和最平凡的柔...
    十三十二十三阅读 241评论 2 5
  • 基于element-ui的cdn打包,网上搜到的一些教程非常坑,总是不说关键的细节。 一、3.x 在build/w...
    凌康ACG阅读 2,343评论 0 3
  • 晚风轻轻吹拂 清新伴着丝丝凉意 夜幕下的天空 漫天星辰与半月遥相辉映 深邃而宁静 晚风轻轻吹拂 吹起了花儿的芬香 ...
    多果加阅读 536评论 0 0
  • 顾及太多就限制了手和脚的行动能力,做事就唯唯诺诺,不敢下决定,既然决定了,就支持他走出这一步,孩子的问题总会有法子...
    禧珍阅读 339评论 9 8