揭开正则表达式的奇怪面纱

作者:小菜 更新时间:2025-03-16 点击数:
简介:引言正则表达式(regular expression)就是用一个 字符串 来描述一个特征,然后去验证另一个 字符串 是否符合这个特征。

比如 表达式 ab+ 描述

【菜科解读】

引言正则表达式(regular expression)就是用一个 字符串 来描述一个特征,然后去验证另一个 字符串 是否符合这个特征。

比如 表达式 ab+ 描述的特征是 一个 'a' 和 任意个 'b' ,那么 'ab', 'abb', 'abbbbbbbbbb' 都符合这个特征。

正则表达式可以用来:(1)验证字符串是否符合指定特征,比如验证是否是合法的邮件地址。

(2)用来查找字符串,从一个长的文本中查找符合指定特征的字符串,比查找固定字符串更加灵活方便。

(3)用来替换,比普通的替换更强大。

正则表达式学习起来其实是很简单的,不多的几个较为抽象的概念也很容易理解。

之所以很多人感觉正则表达式比较复杂,一方面是因为大多数的文档没有做到由浅入深地讲解,概念上没有注意先后顺序,给读者的理解带来困难;另一方面,各种引擎自带的文档一般都要介绍它特有的功能,然而这部分特有的功能并不是我们首先要理解的。

文章中的每一个举例,都可以点击进入到测试页面进行测试。

闲话少说,开始。

1. 正则表达式规则1.1 普通字符字母、数字、汉字、下划线、以及后边章节中没有特殊定义的标点符号,都是"普通字符"。

表达式中的普通字符,在匹配一个字符串的时候,匹配与之相同的一个字符。

举例1:表达式 "c",在匹配字符串 "abcde" 时,匹配结果是:成功;匹配到的内容是:"c";匹配到的位置是:开始于2,结束于3。

(注:下标从0开始还是从1开始,因当前编程语言的不同而可能不同)

举例2:表达式 "bcd",在匹配字符串 "abcde" 时,匹配结果是:成功;匹配到的内容是:"bcd";匹配到的位置是:开始于1,结束于4。

1.2 简单的转义字符一些不便书写的字符,采用在前面加 "\" 的方法。

这些字符其实我们都已经熟知了。

还有其他一些在后边章节中有特殊用处的标点符号,在前面加 "\" 后,就代表该符号本身。

比如:^, $ 都有特殊意义,如果要想匹配字符串中 "^" 和 "$" 字符,则表达式就需要写成 "\^" 和 "\$"。

这些转义字符的匹配方法与 "普通字符" 是类似的。

也是匹配与之相同的一个字符。

举例1:表达式 "\$d",在匹配字符串 "abc$de" 时,匹配结果是:成功;匹配到的内容是:"$d";匹配到的位置是:开始于3,结束于5。

1.3 能够与 '多种字符' 匹配的表达式正则表达式中的一些表示方法,可以匹配 '多种字符' 其中的任意一个字符。

比如,表达式 "\d" 可以匹配任意一个数字。

虽然可以匹配其中任意字符,但是只能是一个,不是多个。

这就好比玩扑克牌时候,大小王可以代替任意一张牌,但是只能代替一张牌。

举例1:表达式 "\d\d",在匹配 "abc123" 时,匹配的结果是:成功;匹配到的内容是:"12";匹配到的位置是:开始于3,结束于5。

举例2:表达式 "a.\d",在匹配 "aaa100" 时,匹配的结果是:成功;匹配到的内容是:"aa1";匹配到的位置是:开始于1,结束于4。

1.4 自定义能够匹配 '多种字符' 的表达式使用方括号 [ ] 包含一系列字符,能够匹配其中任意一个字符。

用 [^ ] 包含一系列字符,则能够匹配其中字符之外的任意一个字符。

同样的道理,虽然可以匹配其中任意一个,但是只能是一个,不是多个。

举例1:表达式 "[bcd][bcd]" 匹配 "abc123" 时,匹配的结果是:成功;匹配到的内容是:"bc";匹配到的位置是:开始于1,结束于3。

举例2:表达式 "[^abc]" 匹配 "abc123" 时,匹配的结果是:成功;匹配到的内容是:"1";匹配到的位置是:开始于3,结束于4。

1.5 修饰匹配次数的特殊符号前面章节中讲到的表达式,无论是只能匹配一种字符的表达式,还是可以匹配多种字符其中任意一个的表达式,都只能匹配一次。

如果使用表达式再加上修饰匹配次数的特殊符号,那么不用重复书写表达式就可以重复匹配。

使用方法是:"次数修饰"放在"被修饰的表达式"后边。

比如:"[bcd][bcd]" 可以写成 "[bcd]{2}"。

举例1:表达式 "\d+\.?\d*" 在匹配 "It costs $12.5" 时,匹配的结果是:成功;匹配到的内容是:"12.5";匹配到的位置是:开始于10,结束于14。

举例2:表达式 "go{2,8}gle" 在匹配 "Ads by goooooogle" 时,匹配的结果是:成功;匹配到的内容是:"goooooogle";匹配到的位置是:开始于7,结束于17。

1.6 其他一些代表抽象意义的特殊符号一些符号在表达式中代表抽象的特殊意义:

进一步的文字说明仍然比较抽象,因此,举例帮助大家理解。

举例1:表达式 "^aaa" 在匹配 "xxx aaa xxx" 时,匹配结果是:失败。

因为 "^" 要求与字符串开始的地方匹配,因此,只有当 "aaa" 位于字符串的开头的时候,"^aaa" 才能匹配,比如:"aaa xxx xxx"。

举例2:表达式 "aaa$" 在匹配 "xxx aaa xxx" 时,匹配结果是:失败。

因为 "$" 要求与字符串结束的地方匹配,因此,只有当 "aaa" 位于字符串的结尾的时候,"aaa$" 才能匹配,比如:"xxx xxx aaa"。

举例3:表达式 ".\b." 在匹配 "@@@abc" 时,匹配结果是:成功;匹配到的内容是:"@a";匹配到的位置是:开始于2,结束于4。

进一步说明:"\b" 与 "^" 和 "$" 类似,本身不匹配任何字符,但是它要求它在匹配结果中所处位置的左右两边,其中一边是 "\w" 范围,另一边是 非"\w" 的范围。

举例4:表达式 "\bend\b" 在匹配 "weekend,endfor,end" 时,匹配结果是:成功;匹配到的内容是:"end";匹配到的位置是:开始于15,结束于18。

举例5:表达式 "Tom|Jack" 在匹配字符串 "I'm Tom, he is Jack" 时,匹配结果是:成功;匹配到的内容是:"Tom";匹配到的位置是:开始于4,结束于7。

匹配下一个时,匹配结果是:成功;匹配到的内容是:"Jack";匹配到的位置时:开始于15,结束于19。

举例6:表达式 "(go\s*)+" 在匹配 "Let's go go go!" 时,匹配结果是:成功;匹配到内容是:"go go go";匹配到的位置是:开始于6,结束于14。

举例7:表达式 "¥(\d+\.?\d*)" 在匹配 "$10.9,¥20.5" 时,匹配的结果是:成功;匹配到的内容是:"¥20.5";匹配到的位置是:开始于6,结束于10。

单独获取括号范围匹配到的内容是:"20.5"。

2.1 匹配次数中的贪婪与非贪婪 在使用修饰匹配次数的特殊符号时,有几种表示方法可以使同一个表达式能够匹配不同的次数,比如:"{m,n}", "{m,}", "?", "*", "+",具体匹配的次数随被匹配的字符串而定。

这种重复匹配不定次数的表达式在匹配过程中,总是尽可能多的匹配。

比如,针对文本 "dxxxdxxxd",举例如下: "\w+" 将匹配第一个 "d" 和最后一个 "d" 之间的所有字符 "xxxdxxx"。

虽然 "\w+" 也能够匹配上最后一个 "d",但是为了使整个表达式匹配成功,"\w+" 可以 "让出" 它本来能够匹配的最后一个 "d" 由此可见,"\w+" 在匹配的时候,总是尽可能多的匹配符合它规则的字符。

虽然第二个举例中,它没有匹配最后一个 "d",但那也是为了让整个表达式能够匹配成功。

同理,带 "*" 和 "{m,n}" 的表达式都是尽可能地多匹配,带 "?" 的表达式在可匹配可不匹配的时候,也是尽可能的 "要匹配"。

这种匹配原则就叫作 "贪婪" 模式。

非贪婪模式: 在修饰匹配次数的特殊符号后再加上一个 "?" 号,则可以使匹配次数不定的表达式尽可能少的匹配,使可匹配可不匹配的表达式,尽可能的 "不匹配"。

这种匹配原则叫作 "非贪婪" 模式,也叫作 "勉强" 模式。

如果少匹配就会导致整个表达式匹配失败的时候,与贪婪模式类似,非贪婪模式会最小限度的再匹配一些,以使整个表达式匹配成功。

举例如下,针对文本 "dxxxdxxxd" 举例: 为了让整个表达式匹配成功,"\w+?" 不得不匹配 "xxx" 才可以让后边的 "d" 匹配,从而使整个表达式匹配成功。

因此,结果是:"\w+?" 匹配 "xxx" 举例1:表达式 "(.*)" 与字符串 "

aa

bb

" 匹配时,匹配的结果是:成功;匹配到的内容是 "

aa

bb

" 整个字符串,表达式中的 "" 将与字符串中最后一个 "" 匹配。

举例2:相比之下,表达式 "(.*?)" 匹配举例1中同样的字符串时,将只得到 "

aa

",再次匹配下一个时,可以得到第二个 "

bb

"。

2.2 反向引用 \1, \2... 表达式在匹配时,表达式引擎会将小括号 "( )" 包含的表达式所匹配到的字符串记录下来。

在获取匹配结果的时候,小括号包含的表达式所匹配到的字符串可以单独获取。

这一点,在前面的举例中,已经多次展示了。

在实际应用场合中,当用某种边界来查找,而所要获取的内容又不包含边界时,必须使用小括号来指定所要的范围。

比如前面的 "(.*?)"。

其实,"小括号包含的表达式所匹配到的字符串" 不仅是在匹配结束后才可以使用,在匹配过程中也可以使用。

表达式后边的部分,可以引用前面 "括号内的子匹配已经匹配到的字符串"。

引用方法是 "\" 加上一个数字。

"\1" 引用第1对括号内匹配到的字符串,"\2" 引用第2对括号内匹配到的字符串 以此类推,如果一对括号内包含另一对括号,则外层的括号先排序号。

换句话说,哪一对的左括号 "(" 在前,那这一对就先排序号。

举例如下: 举例1:表达式 "('|")(.*?)(\1)" 在匹配 " 'Hello', "World" " 时,匹配结果是:成功;匹配到的内容是:" 'Hello' "。

再次匹配下一个时,可以匹配到 " "World" "。

举例2:表达式 "(\w)\1{4,}" 在匹配 "aa bbbb abcdefg ccccc 111121111 999999999" 时,匹配结果是:成功;匹配到的内容是 "ccccc"。

再次匹配下一个时,将得到 999999999。

这个表达式要求 "\w" 范围的字符至少重复5次,注意与 "\w{5,}" 之间的区别。

举例3:表达式 "(\w+)\s*(\w+(=('|").*?\4)?\s*)*>.*?\1>" 在匹配 "" 时,匹配结果是成功。

如果 "" 与 "" 不配对,则会匹配失败;如果改成其他配对,也可以匹配成功。

2.3 预搜索,不匹配;反向预搜索,不匹配 前面的章节中,我讲到了几个代表抽象意义的特殊符号:"^","$","\b"。

它们都有一个共同点,那就是:它们本身不匹配任何字符,只是对 "字符串的两头" 或者 "字符之间的缝隙" 附加了一个条件。

理解到这个概念以后,本节将继续介绍另外一种对 "两头" 或者 "缝隙" 附加条件的,更加灵活的表示方法。

正向预搜索:"(?=xxxxx)","(?!xxxxx)" 格式:"(?=xxxxx)",在被匹配的字符串中,它对所处的 "缝隙" 或者 "两头" 附加的条件是:所在缝隙的右侧,必须能够匹配上 xxxxx 这部分的表达式。

因为它只是在此作为这个缝隙上附加的条件,所以它并不影响后边的表达式去真正匹配这个缝隙之后的字符。

这就类似 "\b",本身不匹配任何字符。

"\b" 只是将所在缝隙之前、之后的字符取来进行了一下判断,不会影响后边的表达式来真正的匹配。

举例1:表达式 "Windows (?=NT|XP)" 在匹配 "Windows 98, Windows NT, Windows 2000" 时,将只匹配 "Windows NT" 中的 "Windows ",其他的 "Windows " 字样则不被匹配。

举例2:表达式 "(\w)((?=\1\1\1)(\1))+" 在匹配字符串 "aaa ffffff 999999999" 时,将可以匹配6个"f"的前4个,可以匹配9个"9"的前7个。

这个表达式可以读解成:重复4次以上的字母数字,则匹配其剩下最后2位之前的部分。

当然,这个表达式可以不这样写,在此的目的是作为演示之用。

格式:"(?!xxxxx)",所在缝隙的右侧,必须不能匹配 xxxxx 这部分表达式。

举例3:表达式 "((?!\bstop\b).)+" 在匹配 "fdjka ljfdl stop fjdsla fdj" 时,将从头一直匹配到 "stop" 之前的位置,如果字符串中没有 "stop",则匹配整个字符串。

举例4:表达式 "do(?!\w)" 在匹配字符串 "done, do, dog" 时,只能匹配 "do"。

在本条举例中,"do" 后边使用 "(?!\w)" 和使用 "\b" 效果是一样的。

反向预搜索:"(?,"(?这两种格式的概念和正向预搜索是类似的,反向预搜索要求的条件是:所在缝隙的 "左侧",两种格式分别要求必须能够匹配和必须不能够匹配指定表达式,而不是去判断右侧。

与 "正向预搜索" 一样的是:它们都是对所在缝隙的一种附加条件,本身都不匹配任何字符。

举例5:表达式 "(?\d{4})\d+(?=\d{4})" 在匹配 "1234567890123456" 时,将匹配除了前4个数字和后4个数字之外的中间8个数字。

由于 JScript.RegExp 不支持反向预搜索,因此,本条举例不能够进行演示。

很多其他的引擎可以支持反向预搜索,比如:Java 1.4 以上的 java.util.regex 包,.NET 中System.Text.RegularExpressions 命名空间,以及本站推荐的最简单易用的 DEELX 正则引擎。

3. 其他通用规则 还有一些在各个正则表达式引擎之间比较通用的规则,在前面的讲解过程中没有提到。

3.1 表达式中,可以使用 "\xXX" 和 "\uXXXX" 表示一个字符("X" 表示一个十六进制数)3.2 在表达式 "\s","\d","\w","\b" 表示特殊意义的同时,对应的大写字母表示相反的意义3.4 括号 "( )" 内的子表达式,如果希望匹配结果不进行记录供以后使用,可以使用 "(?:xxxxx)" 格式 举例1:表达式 "(?:(\w)\1)+" 匹配 "a bbccdd efg" 时,结果是 "bbccdd"。

括号 "(?:)" 范围的匹配结果不进行记录,因此 "(\w)" 使用 "\1" 来引用。

3.5 常用的表达式属性设置简介:Ignorecase,Singleline,Multiline,Global 默认情况下,表达式中的字母是要区分大小写的。

配置为 Ignorecase 可使匹配时不区分大小写。

有的表达式引擎,把 "大小写" 概念延伸至 UNICODE 范围的大小写。

默认情况下,小数点 "." 匹配除了换行符(\n)以外的字符。

配置为 Singleline 可使小数点可匹配包括换行符在内的所有字符。

配置为 Multiline 可以使 "^" 匹配①外,还可以匹配换行符之后,下一行开始前③的位置,使 "$" 匹配④外,还可以匹配换行符之前,一行结束②的位置。

4. 其他提示4.1 如果想要了解高级的正则引擎还支持那些复杂的正则语法,可参见本站 DEELX 正则引擎的说明文档。

4.2 如果要要求表达式所匹配的内容是整个字符串,而不是从字符串中找一部分,那么可以在表达式的首尾使用 "^" 和 "$",比如:"^\d+$" 要求整个字符串只有数字。

4.3 如果要求匹配的内容是一个完整的单词,而不会是单词的一部分,那么在表达式首尾使用 "\b",比如:使用 "\b(if|while|else|void|int )\b" 来匹配程序中的关键字。

4.4 表达式不要匹配空字符串。

否则会一直得到匹配成功,而结果什么都没有匹配到。

比如:准备写一个匹配 "123"、"123."、"123.5"、".5" 这几种形式的表达式时,整数、小数点、小数数字都可以省略,但是不要将表达式写成:"\d*\.?\d*",因为如果什么都没有,这个表达式也可以匹配成功。

更好的写法是:"\d+\.?\d*|\.\d+"。

4.5 能匹配空字符串的子匹配不要循环无限次。

如果括号内的子表达式中的每一部分都可以匹配 0 次,而这个括号整体又可以匹配无限次,那么情况可能比上一条所说的更严重,匹配过程中可能死循环。

虽然现在有些正则表达式引擎已经通过办法避免了这种情况出现死循环了,比如 .NET 的正则表达式,但是我们仍然应该尽量避免出现这种情况。

如果我们在写表达式时遇到了死循环,也可以从这一点入手,查找一下是否是本条所说的原因。

4.6 合理选择贪婪模式与非贪婪模式,参见话题讨论。

4.7 或 "|" 的左右两边,对某个字符最好只有一边可以匹配,这样,不会因为 "|" 两边的表达式因为交换位置而有所不同。

正则表达式话题[原创文章,转载请保留或注明出处:http://www.regexlab.com/zh/regtopic.htm]本文将逐步讨论一些正则表达式的使用话题。

本文为本站基础篇之后的扩展,在阅读本文之前,建议先阅读正则表达式参考文档一文。

1. 表达式的递归匹配有时候,我们需要用正则表达式来分析一个计算式中的括号配对情况。

比如,使用表达式 "\( [^)]* \)" 或者 "\( .*? \)" 可以匹配一对小括号。

但是如果括号内还嵌有一层括号的话,如 "( ( ) )",则这种写法将不能够匹配正确,得到的结果是 "( ( )" 。

类似情况的还有 HTML 中支持嵌套的标签如 " " 等。

本节将要讨论的是,想办法把有嵌套的的成对括号或者成对标签匹配出来。

匹配未知层次的嵌套:有的正则表达式引擎,专门针对这种嵌套提供了支持。

并且在栈空间允许的情况下,能够支持任意未知层次的嵌套:比如 Perl,PHP,GRETA 等。

在 PHP 和 GRETA 中,表达式中使用 "(?R)" 来表示嵌套部分。

匹配嵌套了未知层次的 "小括号对" 的表达式写法如下:"\( ([^()] | (?R))* \)"。

[Perl 和 PHP 的示例代码]匹配有限层次的嵌套:对于不支持嵌套的正则表达式引擎,只能通过一定的办法来匹配有限层次的嵌套。

思路如下:第一步,写一个不能支持嵌套的表达式:"\( [^()]* \)","((?!).)*"。

这两个表达式在匹配有嵌套的文本时,只匹配最内层。

第二步,写一个可匹配嵌套一层的表达式:"\( ([^()] | \( [^()]* \))* \)"。

这个表达式在匹配嵌套层数大于一时,只能匹配最里面的两层,同时,这个表达式也能匹配没有嵌套的文本或者嵌套的最里层。

匹配嵌套一层的 "" 标签,表达式为:"((?!).|(((?!).)*))*"。

这个表达式在匹配 "" 嵌套层数大于一的文本时,只匹配最里面的两层。

第三步,找到匹配嵌套(n)层的表达式与嵌套(n-1)层的表达式之间的关系。

比如,能够匹配嵌套(n)层的表达式为: [标记头] ([匹配 [标记头] 和 [标记尾] 之外的表达式] | [匹配 n-1 层的表达式] )* [标记尾] 回头来看前面编写的 可匹配嵌套一层 的表达式: 第四步,依此类推,可以编写出匹配有限(n)层的表达式。

这种方式写出来的表达式,虽然看上去很长,但是这种表达式经过编译后,匹配效率仍然是很高的。

2. 非贪婪匹配的效率 可能有不少的人和我一样,有过这样的经历:当我们要匹配类似 "内容" 或者 "[b]加粗[/b]" 这样的文本时,我们根据正向预搜索功能写出这样的表达式:"([^))*" 或者 "((?!).)*"。

当发现非贪婪匹配之时,恍然大悟,同样功能的表达式可以写得如此简单:".*?"。

顿时间如获至宝,凡是按边界匹配的地方,尽量使用简捷的非贪婪匹配 ".*?"。

特别是对于复杂的表达式来说,采用非贪婪匹配 ".*?" 写出来的表达式的确是简练了许多。

然而,当一个表达式中,有多个非贪婪匹配时,或者多个未知匹配次数的表达式时,这个表达式将可能存在效率上的陷阱。

有时候,匹配速度慢得莫名奇妙,甚至开始怀疑正则表达式是否实用。

效率陷阱的产生: 在本站基础文章里,对非贪婪匹配的描述中说到: 如果少匹配就会导致整个表达式匹配失败的时候,与贪婪模式类似,非贪婪模式会最小限度的再匹配一些,以使整个表达式匹配成功。

具体的匹配过程是这样的:1. "非贪婪部分" 先匹配最少次数,然后尝试匹配 "右侧的表达式"。

2. 如果右侧的表达式匹配成功,则整个表达式匹配结束。

如果右侧表达式匹配失败,则 "非贪婪部分" 将增加匹配一次,然后再尝试匹配 "右侧的表达式"。

3. 如果右侧的表达式又匹配失败,则 "非贪婪部分" 将再增加匹配一次。

再尝试匹配 "右侧的表达式"。

4. 依此类推,最后得到的结果是 "非贪婪部分" 以尽可能少的匹配次数,使整个表达式匹配成功。

或者最终仍然匹配失败。

当一个表达式中有多个非贪婪匹配,以表达式 "d(\w+?)d(\w+?)z" 为例,对于第一个括号中的 "\w+?" 来说,右边的 "d(\w+?)z" 属于它的 "右侧的表达式",对于第二个括号中的 "\w+?" 来说,右边的 "z" 属于它的 "右侧的表达式"。

当 "z" 匹配失败时,第二个 "\w+?" 会 "增加匹配一次",再尝试匹配 "z"。

如果第二个 "\w+?" 无论怎样 "增加匹配次数",直至整篇文本结束,"z" 都不能匹配,那么表示 "d(\w+?)z" 匹配失败,也就是说第一个 "\w+?" 的 "右侧" 匹配失败。

此时,第一个 "\w+?" 会增加匹配一次,然后再进行 "d(\w+?)z" 的匹配。

循环前面所讲的过程,直至第一个 "\w+?" 无论怎么 "增加匹配次数",后边的 "d(\w+?)z" 都不能匹配时,整个表达式才宣告匹配失败。

其实,为了使整个表达式匹配成功,贪婪匹配也会适当的 让出 已经匹配的字符。

因此贪婪匹配也有类似的情况。

当一个表达式中有较多的未知匹配次数的表达式时,为了让整个表达式匹配成功,各个贪婪或非贪婪的表达式都要进行尝试减少或增加匹配次数,由此容易形成一个大循环的尝试,造成了很长的匹配时间。

本文之所以称之为 陷阱 ,因为这种效率问题往往不易察觉。

举例:"d(\w+?)d(\w+?)d(\w+?)z" 匹配 "ddddddddddd..." 时,将花费较长一段时间才能判断出匹配失败。

效率陷阱的避免: 避免效率陷阱的原则是:避免 多重循环 的 尝试匹配 。

并不是说非贪婪匹配就是不好的,只是在运用非贪婪匹配的时候,需要注意避免过多 循环尝试 的问题。

情况一:对于只有一个非贪婪或者贪婪匹配的表达式来说,不存在效率陷阱。

也就是说,要匹配类似 " 内容 " 这样的文本,表达式 "([^))*" 和 "((?!).)*" 和 ".*?" 的效率是完全相同的。

情况二:如果一个表达式中有多个未知匹配次数的表达式,应防止进行不必要的尝试匹配。

比如,对表达式 " script language='(.*?)'>(.*?) /script " 来说,如果前面部分表达式在遇到 " script language='vbscript'>" 时匹配成功后,而后边的 "(.*?) /script " 却匹配失败,将导致第一个 ".*?" 增加匹配次数再尝试。

而对于表达式真正目的,让第一个 ".*?" 增加匹配成 vbscript'> 是不对的,因此这种尝试是不必要的尝试。

因此,对依靠边界来识别的表达式,不要让未知匹配次数的部分跨过它的边界。

前面的表达式中,第一个 ".*?" 应该改写成 "[^']*"。

后边那个 ".*?" 的右边再没有未知匹配次数的表达式,因此这个非贪婪匹配没有效率陷阱。

于是,这个匹配脚本块的表达式,应该写成:" script language='([^']*)'>(.*?) /script " 更好。

揭开,正则,表达式,的,神秘,面纱,引言,正则,

存活上亿年:揭开神秘海洋动物长寿之谜

  海龟数量的正常和稳定是保护海龟的基础。

我们仍然不知道怎样建立正常的海龟数量。

理解雌雄海龟的比例对于保持海龟数量的稳定增长的重要性,对于指导海龟保护措施是非常有帮助的。

  乳头瘤导致大量生存在加勒比海和太平洋海中的海龟都患上了这种肿瘤病。

这种病的发病原因以及在世界范围内迅速蔓延的原因是学者和环保人士最关心的问题之一  气候变化通过各种无法预测的方式对地球造成威胁,海龟也难逃此劫。

气候变化会引起海龟数量结构的变化,因为正在孵化的小海龟的性别取决于孵蛋温度,而海平面上升将会降低海龟进行孵化的海滩温度。

  海龟已经在海洋里生存了1亿多年了。

它们曾是早期人类文化的象征,不断地出现在历史,知识和传说中。

在过去的50年中,海龟是现代科学普遍研究的主题。

而如今,海龟也是媒体的宠儿,每个星期在报纸,杂志或者在线文章中都能看到关于海龟的文章。

在Google里可以搜索到许许多多关于海龟的相关,从科学到娱乐,各种主题应有尽有。

  人们对海龟如此关注,有人可能会认为人类已经非常了解海龟,然而事实并非如此。

跟大自然一样,海龟的自然历史仍然有许多未解之谜。

的确,对于人类已经了解的日蚀,现代科学也还有很多并不了解的方面。

许多关于这些古老创造物的谜团正是激发人类兴趣和同情的力量之一。

如今,海龟面临着从未有过的危机,它们继续生存和长期海里生活的环境出现了问题。

关注海龟并且了解海龟是解救它们的关键。

  2006年8月,全世界许多海龟研究专家聚集在华盛顿,在世界自然保护联盟的海龟专家组提出第三个严重问题之后,表述了保护海龟方面的一些问题。

这个会议还提到了BI:3,很像电影《碟中碟3》,theBI:3小组用“不可能的任务”来定义这些悬而未决的问题,它拥有几个世纪以来积累的第一手经验和来自80多个国家中的300多位世界海龟专家的研究成果。

  设定问题是创建计划和策略的第一步,最终将会填补关键知识的漏洞,并且可以制定合适的保护措施。

BI:3的结果—7个悬而未决的问题在这里得到了描述,强调了关于海龟的一些主要谜团。

他们还提供了一个注重科学发展的框架,知识力量和研究投资。

他们也是公众联系的纽带,发展更多的兴趣和投资来保护海龟和它们的生活环境。

  海龟早在2亿多年前就出现在地球上了,是有名的“活化石”。

据《世界吉尼斯纪录大全》记载,海龟的寿命最长可达152年,是动物中当之无愧的老寿星。

正因为龟是海洋中的长寿动物,所以,沿海人仍将龟视为长寿的吉祥物,就像内地人把松鹤作为长寿的象征一样,沿海的人们也把龟视为长寿的象征,并有“万年龟”之说。

  海龟上颌平出,下颌略向上钩曲,颚喙有锯齿状缺刻。

前额鳞1对。

背甲呈心形。

盾片镶嵌排列。

椎盾5片;肋盾每侧4片;缘盾每侧11片。

四肢桨状。

前肢长1爪于后肢,内侧各具1爪。

雄性尾长,达体长的二分之一。

前肢的爪大而弯曲呈钩状。

背甲橄榄色或棕褐色,杂以浅色斑纹;腹甲黄色。

  最大型的海龟是棱皮龟,长达2米,重达1吨。

最小的是橄榄绿鳞龟,有75厘米长,40公斤重。

  海龟最独特的地方就是龟壳。

它可以保护海龟不受侵犯,让它们在海底自由游动。

除了棱皮龟,所有的海龟都有壳。

棱皮龟有一层很厚的油质皮肤在身上,呈现出5条纵棱。

.  与陆龟不同的是,海龟不能将它们的头部和四肢缩回到壳里。

像翅膀一样的前肢主要用来推动海龟向前,而后肢就像方向舵在游动时掌控方向。

  在成熟之前雄性和雌性海龟的体态是一样的。

当雄性海龟成熟时,尾巴变长变厚,因为生殖器官就在尾巴底部。

  在海洋里生存着7种海龟:棱皮龟、蠵龟、玳瑁、橄榄绿鳞龟、绿海龟、丽龟和平背海龟。

所有的海龟都被列为濒危动物。

生活在中国海洋中的海生龟类有 5种(全世界也只有8种),有绿海龟、玳瑁、蠵(xi)龟、丽龟和棱皮龟。

均被列为国家II级重点保护动物和濒危野生动植物种国际贸易公约(CITES)名录。

其余两种是:大西洋蠵龟和太平洋蠵龟。

#p#分页标题#e#  由于雄性海龟和年幼的海龟不会上岸,我们很难知道生存在野外的海龟数量。

海龟的数量计算一般是根据它们的孵化率。

  研究显示,菜科网,所有种类的幼海龟都不同程度的减少了。

尤其是大海龟和棱皮龟,是所有海龟面临绝种危险最大的种类。

数量最多的是橄榄绿鳞龟,几十万只到印度海岸筑巢。

  大多数的海龟生存在比较浅的沿海水域、海湾、泻湖、珊瑚礁或流入大海的河口。

我们通常在世界各地温暖舒适的海域发现海龟。

  不同种类和同一种类内部不同群体的海龟有着各自的迁徙习惯。

一些海龟游到几公里远的地方筑巢并喂养幼龟。

而棱皮龟迁徙得最远,它们要到5000公里远的海滩筑巢。

而黑龟则喜欢在它们分布区的最南端和最北端繁殖和喂养幼龟。

  海龟保护工作进入高速发展期,沿海经济活动和有害捕鱼作业受到监控。

海龟保护工作已经取得了不少进展。

澳大利亚已经启动了一个投资数百万美元的项目,在社区中开展海龟保护活动,并努力寻找解决鬼网问题的办法。

  印度尼西亚正在进行一项先进的研究,以确定捕鱼业与海龟生存现状的相互关系,并与工业界合作开发适当的缓解措施。

塞舌尔群岛已经制定了创新性的办法,使私营企业参与到实际的保护行动中来。

目前 8个国家已经开始实施侧重于龟类保护的国家计划,而其他十个国家也在计划实施类似的计划。

  几十年来,澳大利亚、阿曼、塞舌尔和南非都在监控各 自的海龟数量;另有几个国家在最近十几年也实施了保护方案。

联合国环境规划署(环境署)曼谷办公室负责统筹该协议执行的Douglas Hykle说,这份国家报告清楚表明,签约国正在作出更大的努力,监测、管理和保护各国的海龟。

人类揭开了“魔鬼公路”神秘的面纱,视觉偏差酿成祸

死亡公路在美国爱达荷州的州立公路上。

地理位置看似非常正常,可车辆一旦进入这一地带就会突然被抛向空中,像有什么力量在故意吸引一样,然后在狠狠地摔到地上,大多车辆会被摔变形,车里的人也会因此伤亡,造成惨重事故。

“魔鬼公路”原因解密在汽车坠入峡谷之前,没有任何刹车的痕迹,感觉是人们自愿地驶入峡谷一般,而且在这条公路上频繁发生类似情况的交通事故,而且没有一个合理的说法来解释这一怪现象。

可是,时隔几年之后,还是被人类揭开了它神秘的面纱!由于公路的特殊的形状地势,当汽车行驶在AB段公路时由于是上坡,这是我们很难判断前方是什么路况,是直路还是拐弯。

当你玩跑车游戏的时候也应该有同感,当车子开向上坡的时候,你不知道前方是什么路,只有到了坡的顶你才能看清楚前方的路。

这样,B ,C两点,也就是峡谷口,被挡住了,只是看见了D 点,这样两条原本并不是连在一起的公路成为了一条公路,这样,悲剧就发生了。

可是,这只是其中的原因之一,因为在B点有醒目的圆柱形护栏。

另一个的原因是太阳光的。

因为这条公路恰好于太阳的移动路线平行。

大家都知道,人之所以能看见东西,是因为有光射进人眼。

经研究发现,事故都发生在上午的11:00-12:00之间,在这一时间段里,恰好护栏被影子所遮挡,在这一时间段里,司机是看不见B点处的护栏的。

“魔鬼公路”的真正秘密现在当地政府已经把这两段公路修建成了一条公路,从此“魔鬼”在这条公路上消失了。

在我们的日常生活中,同样会有许多的感官误差事情的发生,人们也应该清醒的认识到这一点。

如“同构”现象,“矛盾空间”,魔术中大型建筑物的消失等。

人们应该逐渐地认识到这一点,千万别让你的感官欺骗了你!中国公路千千万万,并非每一条都是一马平川绝对安全。

或许是受制于地形,又或许是因为建造上的不合理,本应给人们带来福利的公路却终究成了夺命凶手。

虽然每年在这些“死亡公路”上丧命的人不在少数,冒险者们却依旧对它们趋之若鹜...【查看详情】

加入收藏
               

揭开正则表达式的奇怪面纱

点击下载文档

格式为doc格式

  • 账号登录
社交账号登录