![总结JavaScript的正则与其他语言的不同之处_第1页](http://file3.renrendoc.com/fileroot_temp3/2022-1/9/e83b3f37-5d76-4573-88f5-eec74d6d741a/e83b3f37-5d76-4573-88f5-eec74d6d741a1.gif)
![总结JavaScript的正则与其他语言的不同之处_第2页](http://file3.renrendoc.com/fileroot_temp3/2022-1/9/e83b3f37-5d76-4573-88f5-eec74d6d741a/e83b3f37-5d76-4573-88f5-eec74d6d741a2.gif)
![总结JavaScript的正则与其他语言的不同之处_第3页](http://file3.renrendoc.com/fileroot_temp3/2022-1/9/e83b3f37-5d76-4573-88f5-eec74d6d741a/e83b3f37-5d76-4573-88f5-eec74d6d741a3.gif)
![总结JavaScript的正则与其他语言的不同之处_第4页](http://file3.renrendoc.com/fileroot_temp3/2022-1/9/e83b3f37-5d76-4573-88f5-eec74d6d741a/e83b3f37-5d76-4573-88f5-eec74d6d741a4.gif)
![总结JavaScript的正则与其他语言的不同之处_第5页](http://file3.renrendoc.com/fileroot_temp3/2022-1/9/e83b3f37-5d76-4573-88f5-eec74d6d741a/e83b3f37-5d76-4573-88f5-eec74d6d741a5.gif)
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、总结JavaScript的正则与其他语言的不同之处前言最近发现JavaScript中的正则在某些地方的表现和其他语言或工具中的正则有些不同,比较另类.虽然你几乎不可能写出也几乎用不到下面我讲的这些正则,但是了解一下毕竟是好的.本文中的代码示例都是在兼容ES5的JavaScript环境中执行的,也就是说,IE9之前版本,Fx4左右的版本,等,中的表现很有可能和我下面讲的不一样.1.空字符类不包含任何字符的字符类称之为空字符类(empty char class),我相信你没听别人这么叫过,因为在其他语言中,这种写法是非法的,所有的文档和教程都不会讲一种非法的语法.下面我演示一下其他语言或工具都是怎
2、么报这个错的:?123456789101112131415$echo | grep ''grep: Unmatched or $echo | sed '/'sed:-e 表达式 #1,字符 4:未终止的地址正则表达式$echo | awk '/'awk: cmd. line:1: /awk: cmd. line:1: unterminated regexpawk: cmd. line:1: error: Unmatched or : /$echo | perl -ne '/'Unmatched in regex; marked b
3、y <- HERE in m/ <- HERE / at -e line 1.$echo | ruby -ne '/'-e:1: empty char-class: /$python -c 'import re;re.match("","")'Traceback (most recent call last):File "<string>", line 1, in <module>File "E:Pythonlibre.py", line 137,
4、 in matchreturn _compile(pattern, flags).match(string)File "E:Pythonlibre.py", line 244, in _compileraise error, v # invalid expressionsre_constants.error: lar expression而在JavaScript中,空字符类是合法的正则组成部分,不过它的效果是"永不匹配",也就是匹配什么都会失败.相当于一个空否定正向环视(empty negative lookahead)(?!)的效果:?1234js&g
5、t; "whatevern".match(/g) /空字符类,永不匹配nulljs> "whatevern".match(/(?!)/g) /空否定正向环视,永不匹配null很显然,这种东西在JavaScript中没什么用.2.否定空字符类不包含任何字符的否定字符类称之为否定空字符类(negative empty char class)或者叫空否定字符类(empty negative char class),都可以,因为这个名词是我"自创"的,和上面讲的空字符类类似,这种写法在其他语言中也是非法的:?12345678910111
6、213141516$echo | grep ''grep: Unmatched or $echo | sed '/'sed:-e 表达式 #1,字符 5:未终止的地址正则表达式$echo | awk '/'awk: cmd. line:1: /awk: cmd. line:1: unterminated regexpawk: cmd. line:1: error: Unmatched or : /$echo | perl -ne '/'Unmatched in regex; marked by <- HERE in m/ &
7、lt;- HERE / at -e line 1.$echo | ruby -ne '/'-e:1: empty char-class: /$python -c 'import re;re.match("","")'Traceback (most recent call last):File "<string>", line 1, in <module>File "E:Pythonlibre.py", line 137, in matchreturn _com
8、pile(pattern, flags).match(string)File "E:Pythonlibre.py", line 244, in _compileraise error, v # invalid expressionsre_constants.error: lar expression$而在JavaScript中,否定空字符类是合法的正则组成部分,它的效果和空字符类的效果刚刚相反,它可以匹配任意的字符,包括换行符"n" ,也就是说,等同于常见的sS和wW :?1234js> "whatevern".match(/g
9、) /否定空字符类,匹配任意字符"w", "h", "a", "t", "e", "v", "e", "r", "n"js> "whatevern".match(/sS/g) /互补字符类,匹配任意字符"w", "h", "a", "t", "e", "v", "
10、e", "r", "n"需要注意的是,它不能称之为是"永匹配正则",因为字符类必须要有一个字符才可能匹配,如果目标字符串是空的,或者已经被左边的正则消耗完了,则匹配会失败,比如:?12js> /abc/.test("abc") /c后面没有字符了,匹配失败.false想要了解真正的"永匹配正则",可以看看我以前翻译的一篇文章:"空"正则3.和这个讲起来比较简单,就是:在Perl和其他一些linux命令的正则表达式中,字符类中如果包含了一个紧跟着左方括号的右方括
11、号 ,则这个右方括号会被当作一个普通字符,即只能匹配"",而在JavaScript中,这种正则会被识别成一个空字符类后跟一个右方括号,空字符类什么都不匹配.也类似:在JavaScript中,它匹配的是一个任意字符(否定空字符类)后跟一个右中括号,比如"a","b" ,而在其他语言中,匹配的是任何非的字符.?1234567891011$perl -e 'print "" = /'1$js -e 'print(/.test("")'false$perl -e '
12、;print "x" = /'1$js -e 'print(/.test("x")'false4.$锚点有些初学者认为$匹配的是换行符"n" ,这是大错特错的,$是一个零宽断言(zero-width assertion),它是不可能匹配到一个真正的字符的,它只能匹配一个位置.我要的讲的区别发生在非多行模式中:你也许会认为,在非多行模式中,$匹配的不就是最后一个字符后面的位置吗?实际上没那么简单,在其他大部分语言中,如果目标字符串中的最后一个字符是换行符"n" ,则$还会匹配那个换行符之前的位
13、置,也就是匹配了末尾的换行符左右两边的两个位置.很多语言中都有Z和z这两个表示法,如果你知道它们之间的区别,那你应该就明白了,在其他语言中(Perl,Python,php,Java,c#.),非多行模式下的$相当于Z,而在JavaScript中,非多行模式下的$相当于z(只会匹配最末尾的那个位置,不管最后一个字符是否是换行符).Ruby是个特例,因为它默认就是多行模式,多行模式下$会匹配每个换行符前面的位置,当然也会包括结尾处可能出现的那个换行符.余晟著的正则指引一书中也讲到了这几点.?1234567$perl -e 'print "whatevern" = s/$
14、/替换字符/rg' /全局替换whatever替换字符 /换行符前面的那个位置被替换替换字符 /换行符后面的那个位置被替换$js -e 'print("whatevern".replace(/$/g,"替换字符")' /全局替换whatever替换字符 /换行符后面的那个位置被替换5.点号元字符"."在JavaScript中的正则表达式中,点号元字符"."可以匹配四个行终止符(r-回车符,n-换行符,u2028-行分隔符,u2029-段落分隔符)之外的所有字符,而在其他常用语言中,只会排除掉
15、换行符n.6.向前引用我们都知道正则中有反向引用(back reference),也就是用一个反斜杠+数字的形式引用到前面的某个捕获分组已经匹配到的字符串,目的是用来再次匹配或作为替换结果(变成$).但有种特殊情况是,如果那个被引用的捕获分组还没开始(左括号为界),就使用了反向引用,会怎样.比如正则/(2(a)2/ , (a)是第二个捕获分组,但在它的左边使用了引用它的匹配结果的2,我们知道正则是从左向右进行匹配的,这就是本节的标题向前引用(forwards reference)的来历,它并不是一个严格的概念.那么现在你想想,下面的这句JavaScript代码将返回什么:?12js> /
16、(2(a)2/.exec("aaa")?在回答这个问题之前,先看看其他语言中的表现.同样,在其他语言中,这么写也基本上是无效的:?12345678910$echo aaa | grep '(2(a)2'grep: Invalid back reference$echo aaa | sed -r '/(2(a)2/'sed:-e 表达式 #1,字符 12:非法回引用$echo aaa | awk '/(2(a)2/'$echo aaa | perl -ne 'print /(2(a)2/'$echo aaa |
17、ruby -ne 'print $_ = /(2(a)2/'$python -c 'import re;print re.match("(2(a)2","aaa")'None在awk中没有报错,是因为awk不支持这种反向引用,其中的2被解释成了ASCII码为2的字符.而在Perl Ruby Python中没报错,我不知道为什么这样设计,应该都是学Perl的,但效果都一样,就是这种情况下是不可能匹配成功的.而在JavaScript中,不仅不报错,还能匹配成功,看看和你刚才想的答案一样不一样:?12js> /(2(a)2
18、/.exec("aaa")"aa", "a", "a"防止你忘了exec方法返回的结果是什么,我说一下.第一个元素是完整的匹配字符串,也就是RegExp"$&" ,后面的是每个捕获分组匹配的内容,也就是RegExp.$1和RegExp.$2.为什么能匹配成功呢,匹配过程是怎样的?我的理解是:首先进入了第一个捕获分组(最左边的左括号),其中第一个有效匹配项是2,然而这时第二个捕获分组(a)还没轮上,因此RegExp.$2的值还是undefined,所以2匹配了目标字符串中第一个a左边的一个
19、空字符,或者说"位置",就像和其他零宽断言一样.重点是匹配成功了.继续走,这时第二个捕获分组(a)匹配到了目标字符串中的第一个a,RegExp.$2的值也被赋值为"a",然后是第一个捕获分组结束(最右边的右括号),RegExp.$1的值也是"a".然后是量词2,也就是说,要从目标字符串中的第一个a之后,开始进行正则(2(a)的新的一轮匹配,很关键的一点在这里:就是RegExp.$2的值也就是2匹配的值还是不是第一轮匹配结束时的被赋的值"a",答案是:"不是",RegExp.$1和RegExp.$2的值都会被清空为undefined,1和2又会和第一次一样,成功匹配一个空字符(相当于无任何效果,写不写都一样).成功匹配了目标字符串中的第二个a,这时RegExp.$1和RegExp.$2的值又一次成为了"a",RegExp"$&"的值成为了完整的匹配字符串,前两个a:"aa".在Firefox的早期版本(3.6)中,量词的重新一轮匹配不会清空已有的捕获分组的值,那么也就是说,在第二轮匹配的时候,2会匹配上第二个a,从而:?12j
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 初中物理课件-平面镜成像微
- 《广告法基本培训》课件
- 《超级发廊管理》课件
- 质量基础知识培训课件
- 《资本积累》课件2
- 公共关系练习题练习卷附答案
- 环境监测初级复习试题有答案
- 《DSCDMA信令流程》课件
- 《积极维护人身权》课件
- 《高技术概论》课件
- 迈瑞医疗 -医疗器械-从全球器械巨头发展看迈瑞海外进击之路
- 2014年10月自考00567马列文论选读试题及答案含解析
- 2023届新高考英语语法填空分类强化100题 语法填空之现在分词过去分词100题(思维导图+三年真题+模拟)
- 产科医疗质量安全
- 改善护理服务行动计划总结报告
- 智慧农业整体架构规划设计方案
- 第2课+古代希腊罗马(教学设计)-【中职专用】《世界历史》(高教版2023基础模块)
- 专精特新项目申报简版培训
- 某电厂180m钢筋混凝土烟囱施工方案
- 中储粮兰州公司考试笔试题库
- 重建成长型思维课件
评论
0/150
提交评论