二、入门实例扩展
大家还记得第一篇里提到过的查找重复单词的例子吗?完整解决这个问题只需要perl之类的语言写几行代码。
比如我们想确定每个文件中“ResetSize”出现的次数与“SetSize”出现的次数是否一样多。使用perl命令如下:
% perl -0ne ‘print “$ARGV\n” if s/RestSize//ig != s/SetSize//ig’ *
现在可以不明白这条命令,但要注意到这条命令有多简洁。
perl关于文本处理和正则表达式的许多概念来自两种专业化的语言
awk和sed,非常不同于传统的语言,如C。
2.1 使用正则表达式匹配文本
perl可以以多种方式使用正则表达式,最简单的就是检查变量中的文本能否由某个正则表达式匹配。下面的代码检查$reply中所含的字符串,报告这个字符串是否全部由数字组成:
if ($reply = ~ m/^[0-9]+$/)
{
print “only digits\n”;
}
else
{
print “not only digits\n”;
}
第一行代码也许有些奇怪:正则表达式是“^[0-9]+$”,两边的m/…/告诉perl该对正则表达式进行什么操作。m代表尝试进行“正则表达式匹配 (regular expression match)”。斜线用来标记接线。之前的”=~”用来连接m/…/和欲搜索的字符串,即本例中的$reply。可以把”=~”读作匹配。
上面这个正则不能很好的
匹配浮点数。扩展这个表达式,允许有
负数和
可能的小数部分。
(1)容许负数我们就可以添加“
[+-]?”来处理开头的符号。
(2)容许可能出现的小数我们可以添加”(\.[0-9]*)?”。综合起来就是”^[+-]?[0-9]+(\.[0-9]*)?$”。它能够匹配32,-3.23,+98.3这样的文字。
2.2 成功匹配的副作用
第一篇我们看到某些版本的egrep支持作为元字符的”\1”,”\2”用来保存前面的括号内的子表达式实际匹配的文字。perl和其他许多支持正则表达式的语言都支持这些功能,而且匹配成功之后,在正则表达式之外的代码仍然能引用这些匹配的文本。
但是perl是通过变量$1,$2等来指向第一组,第二组括号内的子表达式实际匹配的文本。
现在我们比较”^[+-]?[0-9]+[CF]$”和”^([+-]?[0-9]+)([CF])$”。添加的括号改变了正则表达式的意义了吗?我们前面知道括号的使用场景,这里既没有改变星号或其他量词的作用对象,也没改变多选分支的范围,也就是这个表达式仍然能够匹配相同的文本。不过,他们确实围住了我们期望匹配字符串中有价值的子表达式。在perl里,第一个括号里的内容就会自动保存到$1里,第二个括号匹配的内容会自动保存到$2里,我们可以在程序里通过$1和$2两个变量来引用匹配到的内容。这个括号也称为
捕获型括号,灰常有用。也就是第一篇说到的括号的三个用途的第三种。
2.3 错综复杂的正则表达式
在perl之类的高级语言中,正则表达式的使用与其程序的逻辑是混合在一起的。针对上面的例子我们再增加一个匹配小数的功能,添加一个”(\.[0-9]*)?”就可以,最终为:
“([+-]?[0-9]+(\.[0-9]*)?)([CF])$”。请注意,增加的匹配小数部分是放在原来的第一个括号内部的,这样$2保存的就是新增的小数部分。
这些都是捕获型括号,会按照从左到右的顺序保存到变量里。但是上例中新增的小数部分可能永远不会单独被引用,这样的话能不被保存到变量里就好了。也就是说需要一个
只能用于分组,而不会影响文本的捕获和变量的保存的非捕获型括号。
perl以及近期出现的其他正则表达式流派提供了这个功能。
“(…)”用来分组和捕获,而“(?:...)”只分组不捕获。(联想下[…]和[^…])。这样“^([+-]?[0-9]+(?:\.[0-9]*)?)([CF])$”中的小数部分就不会被捕获,也不会被保存到变量里了。
我们已经见过不同的字符组之间的冲突。在egrep中,我们把正则表达式包含在单引号中。整个egrep命令行写在command-shell提示符后,shell能认出它自己的元字符。例如,对shell来说,空格符就是一个元字符,它用来分隔命令和参数,或者参数与参数。在许多shell中,单引号是元字符,单引号内的字符串中的字符不需要被当做元字符处理(DOS使用双引号)。在shell中使用引号容许我们在正则表达式中使用空格,否则shell会把空格认作参数之间的分隔符,而不是把整个正则表达式传递给egrep。
在perl的正则表达式中,
“\b”通常是匹配一个单词分界符的,
但在字符组中,它匹配一个退格符。前一篇我们提过,字符组可以看做一个独立的“子语言”,它里面的规范不同于正则表达式主体,这条规则也适用于perl(包括任何其他流派的正则表达式)。
补充:
\b:表示匹配一个位置,并不占用任何字符,这个位置的一侧是单词字符,一侧为非单词字符,或字符串的开始或结束位置。
还可以参考:
http://wenku.baidu.com/link?url=iWQ-tay23mSRdlOOLR9u-FLxGnFd0xEIoLNFBKL9gBGj2E5ek4HaEAgGyVibLO5n5av9IhwVtoSqBXhWonpVkZkonl7RssMTw2qC2UF5ERK
2.3.1 使用\s匹配所有空白
讨论空白的问题时,我们可以使用“[ \t]*”,这样做没问题,但许多流派的正则表达式提供了一种方便的办法:”\s”。”\s”看起来类似”\t”, “\t”代表制表符,而”\s”则能表示所有表示”空白字符(whitespace character)”的字符组,其中包括
空格符,制表符,换行符和回车符。
2.3.2 小结
尽管上面大部分例子是关于perl的,但其思想也适用其他语言。
1. 许多工具都有自己的正则表达式流派。perl和egrep可能属于同一个流派,但perl的正则表达式中的元字符更多。许多其他的语言,如java,python,.net等,他们的流派都类似于perl。
2. perl用$variable =~ m/regex/ 来判断一个正则表达式是否能匹配某个字符串。m表示“匹配”(match),而斜线用来标注正则表达式的边界(他们本身不属于正则表达式)。整个测试语句作为一个单元,返回true或者false。
3. 元字符(具有特殊意义的字符)的定义在正则表达式中并不是统一的。
4. perl和其他流派的正则表达式提供了许多用用的简记法(shorthands):
\t 制表符
\n 换行符
\r 回车符
\s 任何“空白”字符(例如空格符,制表符等)
\S 任何除“\s”之外的字符
\w 表示[a-zA-Z0-9],(\w+很有用,可以用来匹配一个单词)
\W 除\w之外的任何字符,也就是[^a-zA-Z0-9]。
\d [0-9],即数字
\D 除\d之外的任何字符,即[^0-9]。
5. /i修饰符表示此测试不区分大小写。
6. (?:…)可以用来分组文本,但并不捕获。
7. 匹配成功之后,perl可以用$1,$2,$3之类的变量来保存相对应捕获型(…)括号内的子表达式匹配的文本。
2.4 使用正则表达式修改文本
到现在,我们遇到的例子都只是从字符串中提取信息。现在我们来看perl和其他许多语言提供的一个正则表达式特性:
替换(也可以叫做‘查找和替换’)。
我们已经看到,”$var =~ m/regex/”尝试用正则表达式来匹配保存在变量中的文本,并返回表示能否匹配的布尔值.与之类似的结构”
$var =~ s/regex/replacement/”则更进一步:如果正则表达式能够匹配$var中的某段文本,则将这段匹配的文本替换为replacement。其中regex与之前m/…/的用法一样,而replacement(位于第二个和第三个斜线之间,不包括斜线)则作为双引号内的字符串。也就是说,在其中可以使用变量,例如$1和$2来引用之前匹配的具体文本。
如$var的值为”Jeff Friedl”, 那么运行: $var =~ s/Jeff/Jeffrey/;
$var的值就变成”Jeffery Friedl”。如果再运行一次,就得到”Jeffreyrey Friedl”。要避免这种情况,我们就可以添加单词分界符的元字符。perl中的单词分界符是”\b”,:
$var =~ s/\bJeff\b/Jeffery/;
2.4.1 举例:修正股票价格
有时候我们得到的股票价格类似”9.05000037272”,我们希望展示的是”9.05”。抽象一下要求就是:
通常保留小数点后两位数,如果第三位不是零,也需要保留,去掉其他的数字。也就是”12.37500392”或”12.375”会被修正为12.375,而37.500被修正为37.50。
假设$price包含了需要修正的字符串,我么可以用:
$price =~ s/(\.\d\d[1-9]?)\d*/$1/;
解释下:最开始的”\.”匹配小数点。接下来的”\d\d”匹配开头的两位小数.”[1-9]?”匹配可能跟在后面的非零数字。到这里,任何匹配的文本都是我们希望保留的,所以我们用括号把它们保存到$1中,然后将$1放入replacement字符串中。正则表达式的末尾”\d*”用来匹配其他数字,但并不是我们需要保留的,所以在括号外,但必须要有。
补充:这里介绍一个类似匹配时的”/i”的选项”/g”,在替换的时候很有用,/g
全局替换符,如果需要检查的字符串包含多行需要替换的文本,每条替换规则都对所有的行生效,我们就必须使用/g。默认不使用时只替换第一个匹配的文本。这里的例子虽然不涉及这个选项,后面会遇到的。类似 “$var =~ s/regex/replacement/g”
2.5 用环视功能为数值添加逗号
大的数值,如果在其间加入逗号,会更容易理解,如”The US population is 298444215”后面的数值可能写成”298,444,215”更自然。如果用正则表达式来修正句子里的数值该如何做呢?
我们应该从这个数的右边开始,每次数3个数字,如果左边还有数字的话就加入一个逗号。但是正则表达式一般都是从左到右工作的。不过梳理一下思路会发现,逗号应该加在“
左边有数字,右边数字的个数正好事3的倍数的位置”。这样,使用一组相对较新的正则表达式特性:“
环视(look around)”能轻松解决这个问题。
环视结构不匹配任何字符,只匹配文本中的特定位置。这一点与单词分界符”\b”,锚点”^”和”$”相似,但是环视更加通用。
2.5.1 顺序环视 (Look ahead)和逆序环视
一种类型的环视叫“顺序环视”,作为表达式的一部分,顺序环视从左到右查看文本,尝试匹配子表达式,如果能够匹配,就返回匹配成功信息。顺序环视又分肯定型和否定性顺序环视两种,比如肯定性顺序环视(positive look ahead)用特殊的序列”(?=…)”来表示。例如”(?=\d)”表示如果当前位置右边的字符是数字则匹配成功。
另一种环视被称为逆序环视,它从右向左查看文本。他用特殊的序列(?<=…)表示,例如”(?<=\d)”表示如果当前位置的左边是一位数字则匹配成功(也就是说,紧跟在数字后面的位置)。
环视不会占用字符。
在理解顺序环视和其他环视功能时需要特别注意一点,即在检查子表达式能否匹配的过程中,他们本身不会占用任何文本。举例说明,普通正则表达式”Jeffrey”匹配文本”… by Jeffrey Friedl.”则匹配到的是 ,
如果用肯定型顺序环视“(?=Jeffery)”匹配到的位置如下:
顺序环视会检查子表达式能否匹配,但它只寻找能够匹配的位置,而不会占用这些字符,通过与普通正则表达式结合可以得到更精确的匹配,如“(?=Jeffery)Jeff”表示只能匹配”Jeffery”这个单词中的”Jeff”。我们还会发现”Jeff(?=rey)”与它是等价的。
下面我们看下”m/(?<=\bJeff)(?=s\b)/’/g”什么意思?
这个表达式实际上并没有匹配任何字符,只是匹配了一个希望插入撇号的位置。
回到2.5节开始提到的在数字中插入逗号的问题。我们希望给一个很长的数字插入逗号,插入逗号的位置必须满足“左边是数字,右边数字的个数正好是3的倍数”。第二个要求用逆序环视很容易解决,”(?=(\d\d\d)+$)”左边只要有一位数字就能满足“左边有数字”的要求,可以用”(?<=\d)”。结合在一起就是” (?<=\d) (?=(\d\d\d)+$)”。
我们还可以使用非捕获型括号”(?:…)”来限制,得到” (?<=\d) (?=(?:\d\d\d)+$)”,这样做的好处一是不会担心与捕获型括号关联的$1是否会被用到,二是效率更高,因为引擎不需要记忆捕获的文本。
2.5.2 单词分界符和否定环视
现在再来讨论给数字插入逗号的问题,如果一个数字在一个句子中间,例如:
$text = “the population of 298444215 is growing.”;
如果用$text =~ s/(?<=\d)(?=(\d\d\d)++$)/,/g;来插入逗号是不会有效的,因为最后的$要求最后是3的倍数位数字结尾。但是我们也不能直接去掉$,因为去掉后就会把数字变成 … of 2,9,8,4,4,4,215 is growing.(仔细想想)
可能初看起来有些棘手,但我们可以用单词分界符”\b”来替换”$”.尽管我们处理的只是数字,perl的单词概念也能解决这个问题。就像”\w”一样,perl和其他语言都把数字,字母和下划线当做单词的一部分。结果,单词分界符的意思就是,在此位置的一侧是单词(例如数字),另一侧不是(比如行的末尾或空格)。
这个“
一侧如此这般,另一侧如此那般”好像很眼熟,就像前面的顺序环视或逆序环视,这里的区别之一在于,有一侧必须使用否定的匹配。这样看来,迄今为止我们用到的顺序环视和逆序环视都应该被称为
肯定顺序环视和肯定逆序环视。因为他们成功的条件是子表达式在这些位置能够匹配。正则表达式还提供了相对应的否定顺序环视和否定逆序环视。
所以单词分界符的意思是,一侧是”\w”,而另一侧不是”\w”,就可以”(?<!\w)(?=\w)”来表示单词起始分界符,用”(?=\w)(?<!\w)”表示单词结束分界符。两者用或结合起来” (?<!\w)(?=\w)| (?=\w)(?<!\w)”就等价于”\b”(从这里我们也看到,如果不使用括号来限制范围,或’|’的范围无限延伸。比如aa|bb匹配“aa或bb”,(aa)(bb)|(cc)(dd)匹配“(aa)(bb)或(cc)(dd),但是(aa)(bb|cc)(dd)中或的范围就只是”bb或cc””)。如果语言本身不支持”\b”就可以用前者代替,但效率不如直接支持的”\b”。
对于前面的插入逗号的为题,我们真正需要的是”(?!\d)”来标记3位数字的起始计数位置,用它来取代”\b”或”$”得到:
$text =~ s/(?<=\d)(?=(\d\d\d)+(?!\d))/,/g;
2.5.3 不通过逆序环视添加逗号
逆序环视和顺序环视一样,所获的支持十分有限,使用也不广泛。尽管perl现在两者都支持,但许多其他语言不是这样。想一想如果不用逆序环视来解决加逗号的问题可能更有意义:
$text =~ s/(\d)(?=(\d\d\d)+(?!\d))/$1,/g;
与之前的区别在于,开头的”\d”所处的肯定逆序环视编程了捕获型括号,replacement字符串则在逗号之前加入了相应的$1。
如果连顺序环视也不用呢?写成:
$text =~ s/(\d)((\d\d\d)+\b)/$1,$2/g;
可以吗?
结果并非期望,会得到类似”281,421906”的字符串,因为”(\d\d\d)+”匹配的数字属于最终匹配文本,是占位的,不能作为”未匹配”部分供下次匹配。但可以借助语言的循环迭代来处理,一次匹配一个位置。

- 大小: 8.1 KB

- 大小: 12.4 KB

- 大小: 56.6 KB
分享到:
相关推荐
2. 逆序环视的概念 - 逆序环视分为四种类型:`(?<!...)`(否定前瞻)、`(?!...)`(肯定前瞻)、`(?<=...)`(否定后瞻)和`(?=...)`(肯定后瞻)。 - 这些构造不包含在匹配结果中,它们只用来检查当前位置之前的...
顺序环视从左到右进行,逆序环视则从右到左。在匹配过程中,正向环视检查右侧,逆向环视检查左侧,如果发现匹配条件成立,就继续进行下一步匹配,否则失败并尝试下一个可能的位置。 顺序肯定环视`(?=Expression)`在...
本文实例讲述了正则表达式环视概念与用法。分享给大家供大家参考,具体如下: 1.环视又叫预搜索和零宽断言 2.环视又划分为 (?=exp)肯定顺序环视 (?<=exp)肯定逆序环视 (?!exp)否定顺序环视 (?<exp)...
<=[a-z])`是一个肯定逆序环视语法,它指定匹配位置前面必须有一个小写字母。`([A-Z])`是一个分组,匹配一个大写字母,而`$1`代表这个匹配的分组,并在它的前面添加一个下划线`_`。 ### 下划线样式字符串转换为驼峰...
在全球建筑行业不断追求节能与智能化发展的浪潮中,变风量(VAV)系统市场正展现出蓬勃的发展潜力。根据 QYResearch 报告出版商的深入调研统计,预计到 2031 年,全球变风量(VAV)系统市场销售额将飙升至 1241.3 亿元,在 2025 年至 2031 年期间,年复合增长率(CAGR)为 5.8%。这一令人瞩目的数据,不仅彰显了 VAV 系统在当今建筑领域的重要地位,更预示着其未来广阔的市场前景。 变风量系统的起源可追溯到 20 世纪 60 年代的美国。它犹如建筑空调系统中的 “智能管家”,能够敏锐地感知室内负荷或室内所需参数的变化,通过维持恒定的送风温度,自动、精准地调节空调系统的送风量,从而确保室内各项参数始终满足空调系统的严格要求。从系统构成来看,变风量系统主要由四个基本部分协同运作。变风量末端设备,包括 VAV 箱和室温控制器,如同系统的 “神经末梢”,负责接收室内环境变化的信号并做出初步响应;空气处理及输送设备则承担着对空气进行净化、加热、冷却等处理以及高效输送的重任;风管系统,涵盖新风、排风、送风、回风等管道,构建起了空气流通的 “高速公路”;而自动控制系统宛
资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。
内容概要:本文探讨了ChatGPT这种高级语音模式的人工智能聊天机器人与用户的互动对其情绪健康的影响。研究采用了两种互补的方法:大规模平台数据分析和随机对照试验(RCT)。平台数据部分通过对超过400万次对话进行隐私保护的大规模自动化分析以及对4000多名用户的调查,揭示了高频率使用者表现出更多的情感依赖和较低的社会交往意愿。RCT部分则通过近1000名参与者为期28天的研究,发现语音模型相较于文本模型能带来更好的情绪健康效果,但长时间使用可能导致负面后果。此外,初始情绪状态较差的用户在使用更具吸引力的语音模型时,情绪有所改善。 适合人群:对人机交互、情感计算和社会心理学感兴趣的科研人员和技术开发者。 使用场景及目标:本研究旨在为AI聊天机器人的设计提供指导,确保它们不仅能满足任务需求,还能促进用户的心理健康。同时,也为政策制定者提供了关于AI伦理使用的思考。 其他说明:研究强调了长期使用AI聊天机器人可能带来的复杂心理效应,特别是对于那些已经感到孤独或社交孤立的人来说,过度依赖可能会加剧这些问题。未来的研究应该更加关注这些极端情况下的用户体验。
Java 反射(Reflection)是一种强大的机制,允许程序在运行时检查和操作类的成员变量和方法。然而,传统的 `setAccessible(true)` 方式虽然便捷,但存在安全性问题,并且性能相对较低。在 Java 7 引入 `MethodHandle` 后,我们可以通过 `MethodHandles.Lookup.findVirtual()` 提供更优雅、高效的方式来访问对象属性。本文将对比这两种反射方式,并分析它们的优缺点。
loongdomShop.tar.gz
内容概要:本文探讨了不同交互模式(文本、中性语音、吸引人语音)和对话类型(开放式、非个人化、个人化)对聊天机器人使用者的心理社会效果(如孤独感、社交互动、情感依赖、不当使用)的影响。研究表明,在初期阶段,语音型聊天机器人比文本型更能缓解孤独感并减少情感依赖,但随着每日使用时间增加,这种优势逐渐消失,尤其是对于中性语音聊天机器人。此外,个人话题对话略微增加了孤独感,而非个人话题则导致更高的情感依赖。总体而言,高频率使用聊天机器人的用户表现出更多的孤独感、情感依赖和不当使用,同时减少了真实人际交往。研究还发现,某些个体特征(如依恋倾向、情绪回避)使用户更容易受到负面影响。 适合人群:心理学家、社会学家、人工智能研究人员以及关注心理健康和人机交互的专业人士。 使用场景及目标:①帮助理解不同类型聊天机器人对用户心理健康的潜在影响;②为设计更健康的人工智能系统提供指导;③制定政策和规范,确保聊天机器人的安全和有效使用。 其他说明:研究强调了进一步探索聊天机器人管理情感内容而不引发依赖或替代人际关系的重要性,呼吁更多跨学科的研究来评估长期影响。
MP4575GF-Z MP4575 TSSOP-20 降压型可调DC-DC电源芯片
界面设计_SwiftUI_习惯养成_项目管理_1742850611.zip
免安装版的logic软件包。支持波形实时查看。内含驱动文件。
1. **系统名称**:学生毕业离校系统 2. **技术栈**:Java技术、MySQL数据库、Spring Boot框架、B/S架构、Tomcat服务器、Eclipse开发环境 3. **系统功能**: - **管理员功能**:首页、个人中心、学生管理、教师管理、离校信息管理、费用结算管理、论文审核管理、管理员管理、留言板管理、系统管理。 - **学生功能**:首页、个人中心、费用结算管理、论文审核管理、我的收藏管理。 - **教师功能**:首页、个人中心、学生管理、离校信息管理、费用结算管理、论文审核管理。
配套文章:https://blog.csdn.net/gust2013/article/details/139608432
蓝凌OA系统V15.0管理员手册
资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。
mips-gcc520-glibc222编译工具链.zip
app开发
内容概要:本文档详细介绍了Swift编程语言的基础知识,涵盖语言特点、基础语法、集合类型、控制流、函数定义、面向对象编程、可选类型、错误处理、协议与扩展以及内存管理等方面的内容。此外还简要提及了Swift与UIKit/SwiftUI的关系,并提供了进一步学习的资源推荐。通过这份文档,读者可以全面了解Swift的基本概念及其在iOS/macOS/watchOS/tvOS平台的应用开发中的使用方法。 适合人群:初学者或者希望从其他编程语言转向Swift的开发者。 使用场景及目标:帮助读者快速上手Swift编程,掌握其基本语法和特性,能够独立完成简单的程序编写任务,为进一步学习高级主题如并发编程、图形界面设计打下坚实的基础。 阅读建议:由于Swift是一门现代化的语言,拥有许多独特的特性和最佳实践方式,在学习过程中应当多加练习并尝试理解背后的原理。同时利用提供的官方文档和其他辅助材料加深印象。