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

比如 表达式 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万多年以前,确实发生过一场毁灭人类的大洪水。
既然上帝引发的那场大洪水是真实存在的,那么诺亚方舟在哪里? 《圣经》记载的诺亚方舟停泊地点,是土耳其亚拉腊山将近5000米高的冰山上。
穆斯林圣书《古兰经》也记载,诺亚方舟可能停泊在土耳其一座被当地人称为古迪-达哥的山上。
美国卫星勘测照片显示在阿勒山西北角存在着令人难以理解的特殊结构,并认为这可能就是诺亚方舟的遗址。
中国和土耳其联合研究小组发现了,该地点位于土耳其境内积雪覆盖的阿勒山。
只是这个诺亚方舟的遗址却是并未让所有的人信服,有人质疑,遗迹中的木质设施似乎是由柏木制成,并非是圣经中提到的歌斐木。
究竟这是不是传说中的诺亚方舟,如果不是,那么真正的诺亚方舟究竟存不存在,又在哪里? 随机文章世界上十大最神秘的木乃伊,外星人木乃伊毁掉你的三观如果有一天火星撞地球,两者都将毁灭(可能性为0)世界禁用子弹威力惊人,击中人体引爆肌肉内脏(生不如死)揭秘属什么的人不能养龟,兔、龙、狗与乌龟从图不能养(招来厄运)揭秘蜥蜴是恐龙的后代吗,蜥蜴是恐龙的食物/长得像并无亲属关系
一块洗衣池的搓板 揭开了朝鲜新罗文武王的身份之谜
中国建立的时候,朝鲜还没有呢。
但是朝鲜自从建立之后,与中国各个王朝相处融洽,一直以高等级的待遇存立。
不仅如此,每次朝鲜被日本人侵略,中国总是会去帮助朝鲜驱除外敌。
在韩国人心目中,新罗文武王在他们心目中地位非常高。
在公元六六八年的时候,这位国王在的帮助下,统一了半岛,朝鲜在历史上第一次统一。
其深远意义,就像一样,韩国对他有了许多美化。
因为棒子人对他们的祖先极力美化,否认与中国有关系,所以文武王的身份就是一个谜。
中国根据历载,推断文武王是一个来自中国东北的扶余人,而韩国学者则坚称文武王是三韩人,与中国没半点关系。
直到有一天,一块石碑的出土,让韩国学者才知道本国文武王是哪里人。
当时这块石碑出土后,不知道是什么原因,就丢失了,这可是文武墓之碑,其意义就相当于秦一样,是记载一个国家朝代的证据。
后来在韩国一户居民家被发现,而这位居民用这块石碑当洗衣池的搓板,导致这块石碑上的文字经过磨损,有些文字已经缺失了。
看来是因为韩国人没人认识中国字的缘故,否则这个墓碑早就发现了。
人们从墓碑上发现,他们心目中的王,竟是中国秺侯的后人。
早年霍去病攻打匈奴,斩杀和俘虏的匈奴人有十几万之多。
匈奴浑邪王被霍去病打败,向汉人投降,得到了的欢迎。
但是休屠王就非常惨了,他们没有投降,于是汉武帝下令他们的王后成为汉朝的奴隶,两个皇子成了汉朝的马夫。
有一天,汉武帝视察皇家马场,发现了着个匈奴皇子,一问究竟,原来是休屠王的孩子。
于是一高兴,就封他为马监。
因为这支匈奴人的祭天金人被霍去病缴获交给汉武帝,所以汉武帝就以金为姓,赐给了他,称他为,他的弟弟叫金伦。
后来,金日磾为了自己和家族,对汉武帝,虽然曾经是死敌,但是为汉朝鞠躬尽瘁。
他的忠诚、他的谦卑,很快赢得了汉武帝的赏识,他一步步升为高官。
汉武帝极为信任他,并要任命他为辅政大臣,可他却说自己不如,可见其谦虚。
正是因为金日磾的功劳,金家在汉朝存续了140年。
但是之后篡权,被推翻。
当时金日磾家族中有一些族人与王莽结亲,为了自保,这些人连夜逃出京城,进入朝鲜半岛。
此后,金家在朝鲜成为第一大姓,许多人都。
而且金家也是朝鲜的掌权人,自称王族不过分。
随机文章宇宙中最恐怖的生物,肉身畅游太空吸收暗能量(无敌)美国野猫式战斗机,5分钟击落日军5架战机东风5b洲际弹道导弹详解,可携带10枚50万吨当量核弹头威力强悍的硬币散弹枪,可以装填各种物体的散弹枪(铁丝/石头/硬币)宇宙到底有没有尽头,如果有那么宇宙之外会是什么