﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-过年-&gt; 过年了！！！天天过年-随笔分类-JAVA杂谈</title><link>http://www.blogjava.net/jackylpz/category/9639.html</link><description>目标 --&gt; 每天都要象过年一样！！！</description><language>zh-cn</language><lastBuildDate>Fri, 02 Mar 2007 03:09:49 GMT</lastBuildDate><pubDate>Fri, 02 Mar 2007 03:09:49 GMT</pubDate><ttl>60</ttl><item><title>java 代码查询网站 </title><link>http://www.blogjava.net/jackylpz/archive/2006/04/26/43283.html</link><dc:creator>过年</dc:creator><author>过年</author><pubDate>Wed, 26 Apr 2006 06:38:00 GMT</pubDate><guid>http://www.blogjava.net/jackylpz/archive/2006/04/26/43283.html</guid><wfw:comment>http://www.blogjava.net/jackylpz/comments/43283.html</wfw:comment><comments>http://www.blogjava.net/jackylpz/archive/2006/04/26/43283.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jackylpz/comments/commentRss/43283.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jackylpz/services/trackbacks/43283.html</trackback:ping><description><![CDATA[<h2><a id="viewpost1_TitleUrl" href="http://www.blogjava.net/beike/articles/36553.html">java 代码查询网站</a> </h2>
1.&nbsp;java2s &nbsp;<a href="http://www.java2s.com/">http://www.java2s.com/</a>
<div>&nbsp;&nbsp;&nbsp;这个网站非常好，分成三大类，分别是<font color="#003399" size="2"><a href="http://www.java2s.com/">Example</a></font>、<font size="2"><a href="http://www.java2s.com/Product/CatalogProduct.htm"><font color="#003399">Products</font></a><font color="#003399">、</font></font><u><font color="#800080">Articles</font></u>，每个大类下又分别设许多小类，还有搜索功能，这样查找起来非常方便。。比如，如果要学习SWT/JFace，只要把Example下的<a href="http://www.java2s.com/Code/Java/SWT-JFace-Eclipse/CatalogSWT-JFace-Eclipse.htm"><strong>SWT JFace Eclipse</strong></a><strong></strong>研究一下也就可以了。另外，这个网站还有<a href="http://www.java2s.com/Code/JavaScript/CatalogJavaScript.htm"><font color="#003399" size="2">JavaScript DHTML</font></a>、 <a href="http://www.java2s.com/Code/CSharp/CatalogCSharp.htm"><font color="#003399" size="2">C# / C Sharp</font></a>、 <a href="http://www.java2s.com/Code/C/CatalogC.htm"><font color="#003399" size="2">C / ANSI-C</font></a>、 <a href="http://www.java2s.com/Code/SQL/CatalogSQL.htm"><font color="#003399" size="2">SQL / MySQL</font></a>等类。总之，非常好。<br /></div>
<div>&nbsp;&nbsp;2. codeZoo <a href="http://www.codezoo.com/">http://www.codezoo.com/</a></div>
<div>&nbsp;&nbsp; 这是O'Reily旗下的，除了Java之外，还有Ruby、Python。</div>
<div>&nbsp;</div>
<div>&nbsp; 3. Java学习源代码检索系统&nbsp; <a href="http://www.chinaitlab.com/www/school/codesearch/index.html">http://www.chinaitlab.com/www/school/codesearch/index.html</a></div>
<div>&nbsp;&nbsp; 难得看见国产的，好歹也要支持一下，分类也算清楚。</div>
<div>&nbsp;</div>
<div>&nbsp; 4. Koders&nbsp; <a href="http://www.koders.com/">http://www.koders.com/</a></div>
<div>&nbsp;&nbsp;&nbsp;是个综合查询的网站，不过它好像是从代码中查找关键词，包含的语言挺多的。</div>
<div>&nbsp; </div>
<div>&nbsp; 5. Resources for Java server-side developers&nbsp; <a href="http://www.java201.com/">http://www.java201.com/</a></div>
<div>&nbsp;&nbsp; 确切的说，它是一个资源收集的网站，代码查询并不多。不过它分类相当细，如Articles、Books、Examples、Extensions、Frameworks等类，你可以输入Spring或Hibernate作为关键词搜索一下看看。<br />&nbsp; 6. http://www.codase.com<br /></div><img src ="http://www.blogjava.net/jackylpz/aggbug/43283.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jackylpz/" target="_blank">过年</a> 2006-04-26 14:38 <a href="http://www.blogjava.net/jackylpz/archive/2006/04/26/43283.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java正则表达式技巧总结</title><link>http://www.blogjava.net/jackylpz/archive/2006/04/24/42851.html</link><dc:creator>过年</dc:creator><author>过年</author><pubDate>Mon, 24 Apr 2006 08:45:00 GMT</pubDate><guid>http://www.blogjava.net/jackylpz/archive/2006/04/24/42851.html</guid><wfw:comment>http://www.blogjava.net/jackylpz/comments/42851.html</wfw:comment><comments>http://www.blogjava.net/jackylpz/archive/2006/04/24/42851.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jackylpz/comments/commentRss/42851.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jackylpz/services/trackbacks/42851.html</trackback:ping><description><![CDATA[这里我总结了一下正则表达式：<br />匹配中文字符的正则表达式： [\u4e00-\u9fa5]<br />匹配双字节字符(包括汉字在内)：[^\x00-\xff]<br />应用：计算字符串的长度（一个双字节字符长度计2，ASCII字符计1）<br />String.prototype.len=function(){return this.replace([^\x00-\xff]/g,&quot;aa&quot;).length;}<br /><br />匹配空行的正则表达式：\n[\s| ]*\r<br /><br />匹配HTML标记的正则表达式：/&lt;(.*)&gt;.*&lt;\/\1&gt;|&lt;(.*) \/&gt;/ <br /><br />匹配首尾空格的正则表达式：(^\s*)|(\s*$)<br /><br />应用：javascript中没有像vbscript那样的trim函数，我们就可以利用这个表达式来实现，如下：<br />String.prototype.trim = function()<br />{<br />return this.replace(/(^\s*)|(\s*$)/g, &quot;&quot;);<br />}<br />利用正则表达式分解和转换IP地址：<br />下面是利用正则表达式匹配IP地址，并将IP地址转换成对应数值的Javascript程序：<br />function IP2V(ip)<br />{<br />re=/(\d+)\.(\d+)\.(\d+)\.(\d+)/g //匹配IP地址的正则表达式<br />if(re.test(ip))<br />{<br />return RegExp.$1*Math.pow(255,3))+RegExp.$2*Math.pow(255,2))+RegExp.$3*255+RegExp.$4*1<br />}<br />else<br />{<br />throw new Error(&quot;Not a valid IP address!&quot;)<br />}<br />}<br /><br />不过上面的程序如果不用正则表达式，而直接用split函数来分解可能更简单，程序如下：<br />var ip=&quot;10.100.20.168&quot;<br />ip=ip.split(&quot;.&quot;)<br />alert(&quot;IP值是：&quot;+(ip[0]*255*255*255+ip[1]*255*255+ip[2]*255+ip[3]*1))<br />匹配Email地址的正则表达式：\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*<br />匹配网址URL的正则表达式：http://([\w-]+\.)+[\w-]+(/[\w- ./?%&amp;=]*)?<br />我原来在CSDN上发贴寻求一个表达式来实现去除重复字符的方法，最终没有找到，这是我能想到的最简单的实现方法。思路是使用后向引用取出包括重复的字符，再以重复的字符建立第二个表达式，取到不重复的字符，两者串连。这个方法对于字符顺序有要求的字符串可能不适用。<br />得用正则表达式从URL地址中提取文件名的javascript程序，如下结果为page1<br />s=&quot;http://www.9499.net/page1.htm&quot;<br />s=s.replace(/(.*\/){0,}([^\.]+).*/ig,&quot;$2&quot;)<br />alert(s)<br />利用正则表达式限制网页表单里的文本框输入内容：<br />用正则表达式限制只能输入中文：onkeyup=&quot;value=value.replace(/[^\u4E00-\u9FA5]/g,&amp;#39;&amp;#39;)&quot; onbeforepaste=&quot;clipboardData.setData(&amp;#39;text&amp;#39;,clipboardData.getData(&amp;#39;text&amp;#39;).replace(/[^\u4E00-\u9FA5]/g,&amp;#39;&amp;#39;))&quot;<br />用正则表达式限制只能输入全角字符： onkeyup=&quot;value=value.replace(/[^\uFF00-\uFFFF]/g,&amp;#39;&amp;#39;)&quot; onbeforepaste=&quot;clipboardData.setData(&amp;#39;text&amp;#39;,clipboardData.getData(&amp;#39;text&amp;#39;).replace(/[^\uFF00-\uFFFF]/g,&amp;#39;&amp;#39;))&quot;<br />用正则表达式限制只能输入数字：onkeyup=&quot;value=value.replace(/[^\d]/g,&amp;#39;&amp;#39;) &quot;onbeforepaste=&quot;clipboardData.setData(&amp;#39;text&amp;#39;,clipboardData.getData(&amp;#39;text&amp;#39;).replace(/[^\d]/g,&amp;#39;&amp;#39;))&quot;<br />用正则表达式限制只能输入数字和英文：onkeyup=&quot;value=value.replace(/[\W]/g,&amp;#39;&amp;#39;) &quot;onbeforepaste=&quot;clipboardData.setData(&amp;#39;text&amp;#39;,clipboardData.getData(&amp;#39;text&amp;#39;).replace(/[^\d]/g,&amp;#39;&amp;#39;))&quot;<br /><img src ="http://www.blogjava.net/jackylpz/aggbug/42851.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jackylpz/" target="_blank">过年</a> 2006-04-24 16:45 <a href="http://www.blogjava.net/jackylpz/archive/2006/04/24/42851.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>破译天书！正则表达式学习心得体会</title><link>http://www.blogjava.net/jackylpz/archive/2006/04/24/42846.html</link><dc:creator>过年</dc:creator><author>过年</author><pubDate>Mon, 24 Apr 2006 08:36:00 GMT</pubDate><guid>http://www.blogjava.net/jackylpz/archive/2006/04/24/42846.html</guid><wfw:comment>http://www.blogjava.net/jackylpz/comments/42846.html</wfw:comment><comments>http://www.blogjava.net/jackylpz/archive/2006/04/24/42846.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jackylpz/comments/commentRss/42846.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jackylpz/services/trackbacks/42846.html</trackback:ping><description><![CDATA[<p><strong><font color="#339900"><font color="#000000">前言</font>
<p>　　Regular Expressions(正则表达式，以下用RE称呼)对小弟来说一直都是神密的地带，看到一些网络上的大大，简单用RE就决解了某些文字的问题，小弟便兴起了学一学RE的想法，但小弟天生就比较懒一些，总希望看有没有些快速学习的方式，于是小弟又请出Google大神，藉由祂的神力，小弟在网络上找到了Jim Hollenhorst先生的文章，经过了阅读，小弟觉得真是不错，所以就做个小心得报告，跟Move-to.Net的朋友分享，希望能为各位大大带来一丁点在学习RE时的帮助。Jim Hollenhorst大大文章之网址如下，有需要的大大可直接连结。</p>
<p>[Blocked Ads]　　The 30 Minute Regex Tutorial By Jim Hollenhorst</p>
<p>　　<a href="http://www.codeproject.com/useritems/RegexTutorial.asp"><font color="#002c99">http://www.codeproject.com/useritems/RegexTutorial.asp</font></a></p>
<h4>　　什么是RE?</h4>
<p>　　想必各位大大在做文件查找的时侯都有使用过万用字符&rdquo;*&rdquo;，比如说想查找在Windows目录下所有的Word文件时，你可能就会用&rdquo;*.doc&rdquo;这样的方式来做查找，因为&rdquo;*&rdquo;所代表的是任意的字符。RE所做的就是类似这样的功能，但其功能更为强大。</p>
<p>　　写程序时，常需要比对字符串是否符合特定样式，RE最主要的功能就是来描述这特定的样式，因此可以将RE视为特定样式的描述式，举个例子来说，&rdquo;\w+&rdquo;所代表的就是任何字母与数字所组成的非空字符串(non-null string)。在.NET framework中提供了非常强大的类别库，藉此可以很轻易的使用RE来做文字的查找与取代、对复杂标头的译码及验证文字等工作。</p>
<p>　　学习RE最好的方式就是藉由例子亲自来做做看。Jim Hollenhorst大大也提供了一个工具程序Expresso(来杯咖啡吧)，来帮助我们学习RE，下载的网址是<a href="http://www.codeproject.com/useritems/RegexTutorial/ExpressoSetup2_1C.zip"><font color="#002c99">http://www.codeproject.com/useritems/RegexTutorial/ExpressoSetup2_1C.zip</font></a>。</p>
<p>　　接下来，就让我们来体验一些例子吧。</p>
<h4>　　一些简单的例子</h4>
<p>　　假设要查找文章中Elvis后接有alive的文字符串的话，使用RE可能会经过下列的过程，括号是所下RE的意思：</p>
<p>　　1. elvis (查找elvis)</p>
<p>　　上述代表所要查找的字符顺序为elvis。在.NET中可以设定乎略字符的大小写，所以&rdquo;Elvis&rdquo;、&rdquo;ELVIS&rdquo;或者是&rdquo;eLvIs&rdquo;都是符合1所下的RE。但因为这只管字符出现的顺序为elvis，所以pelvis也是符合1所下的RE。可以用2的RE来改进。</p>
<p>　　2. \belvis\b (将elvis视为一整体的字查找，如elvis、Elvis乎略字符大小写时)<br />&ldquo;\b&rdquo;在RE中有特别的意思，在上述的例子中所指的就是字的边界，所以\belvis\b用\b把elvis的前后边界界定出来，也就是要elvis这个字。</p>
<p>　　假设要将同一行里elvis后接有alive的文字符串找出来，此时就会用到另外二个特别意义的字符&rdquo;.&rdquo;及&rdquo;*&rdquo;。&rdquo;.&rdquo;所代表就是除了换行字符的任意字符，而&rdquo;*&rdquo;所代表的是重复*之前项目直到找到符合RE的字符串。所以&rdquo;.*&rdquo;所指的就是除了换行字符外的任意数目的字符数。所以查找同一行里elvis后接有alive的文字符串找出来，则可下如3之RE。</p>
<p>　　3. \belvis\b.*\balive\b (查找elvis后面接有alive的文字符串，如elvis is alive)</p>
<p>　　用简单之特别字符就可以组成功能强大的RE，但也发现当使用越来越多的特别字符时，RE就会越来越难看得懂了。<br />再看看另外的例子</p>
<p>　　组成有效的电话号码</p>
<p>　　假使要从网页上收集顾客格式为xxx-xxxx的7位数字的电话号码，其中x是数字，RE可能会这样写。</p>
<p>　　4. \b\d\d\d-\d\d\d\d (查找七位数字之电话号码，如123-1234)<br />　　每一个\d代表一个数字。&rdquo;-&rdquo;则是一般的连字符号，为避免太多重复的\d，RE可以改写成如5的方式。</p>
<p>　　5. \b\d{3}-\d{4} (查找七位数字电话号码较好的方法，如123-1234)<br />　　在\d后的{3}，代表重复前一个项目三次，也就是相等于\d\d\d。</p>
<p>　　RE的学习及测试工具 Expresso</p>
<p>　　因为RE不易阅读及使用者容易会下错RE的特性，Jim大大开发了一个工具软件Expresso，用来帮助使用者学习及测试RE，除了上面所述的网址之外，也可以上Ultrapico网站(<a href="http://www.ultrapico.com/"><font color="#002c99">http://www.Ultrapico.com</font></a>)。安装完Expresso后，在Expression Library中，Jim大大把文章的例子都建立在其中，可以边看文章边测试，也可以试着修改范例所下的RE，马上可以看到结果，小弟觉得非常好用。各位大大可以试试。</p>
<h4>　　.NET中RE的基础概念</h4>
<p>　　特殊字符</p>
<p>　　有些字符有特别的意义，比如之前所看到的&rdquo;\b&rdquo;、&rdquo;.&rdquo;、&rdquo;*&rdquo;、&rdquo;\d&rdquo;等。&rdquo;\s&rdquo;所代表的是任意空格符，比如说spaces、tabs、newlines等.。&rdquo;\w&rdquo;代表是任意字母或数字字符。</p>
<h4>　　再看一些例子吧</h4>
<p>　　6. \ba\w*\b (查找a开头的字，如able)<br />　　这RE描述要查找一个字的开始边界(\b)，再来是字母&rdquo;a&rdquo;，再加任意数目的字母数字(\w*)，再接结束这个字的结束边界(\b)。</p>
<p>　　7. \d+ (查找数字字符串)<br />　　&ldquo;+&rdquo;和&rdquo;*&rdquo;非常相似，除了+至少要重复前面的项目一次。也就是说至少有一个数字。</p>
<p>　　8. \b\w{6}\b (查找六个字母数字的字，如ab123c)</p>
<p>　　下表为RE常用的特殊字符</p>
<p>　　. 除了换行字符的任意字符<br />　　\w 任意字母数字字符<br />　　\s 任意空格符<br />　　\d 任意数字字符<br />　　\b 界定字的边界<br />　　^ 文章的开头，如&rdquo;^The'' 用以表示出现于文章开头的字符串为&rdquo;The&rdquo;<br />　　$ 文章的结尾，如&rdquo;End$&rdquo;用以表示出现在文章的结尾为&rdquo;End&rdquo;<br />　　特殊字符&rdquo;^&rdquo;及&rdquo;$&rdquo;是用来查找某些字必需是文章的开头或结尾，这在验证输入是否符合某一样式时特别用有，比如说要验证七位数字的电话号码，可能会输入如下9的RE。</p>
<p>　　9. ^\d{3}-\d{4}$ (验证七位数字之电话号码)</p>
<p>　　这和第5个RE相同，但其前后都无其它的字符，也就是整串字符串只有这七个数字的电话号码。在.NET中如果设定Multiline这个选项，则&rdquo;^&rdquo;和&rdquo;$&rdquo;会每行进行比较，只要某行的开头结尾符合RE即可，而不是整个文章字符串做一次比较。</p>
<p>　　转意字符(Escaped characters)</p>
<p>　　有时可能会需要&rdquo;^&rdquo;、&rdquo;$&rdquo;单纯的字面意义(literal meaning)而不要将它们当成特殊字符，此时&rdquo;\&rdquo;字符就是用来移除特殊字符特别意义的字符，因此&rdquo;\^&rdquo;、&rdquo;\.&rdquo;、&rdquo;\\&rdquo;所代表的就是&rdquo;^&rdquo;、&rdquo;.&rdquo;、&rdquo;\&rdquo;的字面意义。</p>
<p>　　重复前述项目</p>
<p>　　在前面看过&rdquo;{3}&rdquo;及&rdquo;*&rdquo;可以用来重复前述字符，之后我们会看到如何用同样的语法重复整个次描述(subexpressions)。下表是使用重复前述项目的一些方式。</p>
<p>　　* 重复任意次数<br />　　+ 重复至少一次<br />　　? 重复零次或一次<br />　　{n} 重复n次<br />　　{n,m} 重复至少n次，但不超过m次<br />　　{n,} 重复至少n次</p>
<p>　　再来试一些例子吧</p>
<p>　　10. \b\w{5,6}\b (查找五个或六个字母数字字符的字，如as25d、d58sdf等)<br />　　11. \b\d{3}\s\d{3}-\d{4} (查找十个数字的电话号码，如800 123-1234)<br />　　12. \d{3}-\d{2}-\d{4} (查找社会保险号码，如 123-45-6789)<br />　　13. ^\w* (每行或整篇文章的第一个字)<br />　　在Espresso可试试有Multiline和没Multiline的不同。<br /></p>
<p>匹配某范围的字符</p>
<p>　　有时需要查找某些特定的字符时怎么辨?这时中括号&rdquo;[]&rdquo;就派上了用场。因此[aeiou]所要查找的是&rdquo;a&rdquo;、&rdquo;e&rdquo;、&rdquo;i&rdquo;、&rdquo;o&rdquo;、&rdquo;u&rdquo;这些元音，[.?!]所要查找的是&rdquo;.&rdquo;、&rdquo;?&rdquo;、&rdquo;!&rdquo;这些符号，在中括号中的特殊字符的特别意义都会被移除，也就是解译成单纯的字面意义。也可以指定某些范围的字符，如&rdquo;[a-z0-9]&rdquo;，所指的就是任意小写字母或任意数字。</p>
<p>　　接下来再看一个比较初复杂查找电话号码的RE例子</p>
<p>　　14. \(?\d{3}[( ] \s?\d{3}[- ]\d{4} (查找十位数字之电话号码，如(080) 333-1234 )</p>
<p>　　这样的RE可查找出较多种格式的电话号码，如(080) 123-4567、511 254 6654等。&rdquo;\(?&rdquo;代表一个或零个左小括号&rdquo;(&ldquo;，而&rdquo;[( ]&rdquo;代表查找一个右小括号&rdquo;)&rdquo;或空格符，&rdquo;\s?&rdquo;指一个或零个空格符组。但这样的RE会将类似&rdquo;800) 45-3321&rdquo;这样的电话找出来，也就是括号没有对称平衡的问题，之后会学到择一(alternatives)来决解这样的问题。</p>
<p>　　不包含在某特定字符组里(Negation)</p>
<p>　　有时需要查找在包含在某特定字符组里的字符，下表说明如何做类似这样的描述。</p>
<p>　　\W 不是字母数字的任意字符<br />　　\S 不是空格符的任意字符<br />　　\D 不是数字字符的任意字符<br />　　\B 不在字边界的位置<br />　　[^x] 不是x的任意字符<br />　　[^aeiou] 不是a、e、i、o、u的任意字符</p>
<p>　　15. \S+ (不包含空格符的字符串)</p>
<p>　　择一(Alternatives)</p>
<p>　　有时会需要查找几个特定的选择，此时&rdquo;|&rdquo;这个特殊字符就派上用场了，举例来说，要查找五个数字及九个数字(有&rdquo;-&rdquo;号)的邮政编码。</p>
<p>　　16. \b\d{5}-\d{4}\b|\b\d{5}\b (查找五个数字及九个数字(有&rdquo;-&rdquo;号)的邮政编码)</p>
<p>　　在使用Alternatives时需要注意的是前后的次序，因为RE在Alternatives中会优先选择符合最左边的项目，16中，如果把查找五个数字的项目放在前面，则这RE只会找到五个数字的邮政编码。了解了择一，可将14做更好的修正。</p>
<p>　　17. (\(\d{3}\)|\d{3})\s?\d{3}[- ]\d{4} (十个数字的电话号码)</p>
<p>　　群组(Grouping)</p>
<p>　　括号可以用来介定一个次描述，经由次描述的介定，可以针对次描述做重复或及他的处理。</p>
<p>　　18. (\d{1,3}\.){3}\d{1,3} (寻找网络地址的简单RE)</p>
<p>　　此RE的意思第一个部分(\d{1,3}\.){3}，所指的是，数字最小一位最多三位，并且后面接有&rdquo;.&rdquo;符号，此类型的共有三个，之后再接一到三位的数字，也就是如192.72.28.1这样的数字。</p>
<p>　　但这样会有个缺点，因为网络地址数字最多只到255，但上述的RE只要是一到三位的数字都是符合的，所以这需要让比较的数字小于256才行，但只单独使用RE并无法做这样的比较。在19中使用择一来将地址的限制在所需要的范围内，也就是0到255。</p>
<p>　　19. ((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?) (寻找网络地址)</p>
<p>　　有没有发觉RE越来越像外星人说的话了?就以简单的寻找网络地址，直接看RE都满难理解的哩。</p>
<p>　　Expresso Analyzer View</p>
<p>　　Expresso提供了一个功能，它可以将所下的RE变成树状的说明，一组组的分开说明，提供了一个好的除错环境。其它的功能，如部分符合(Partial Match只查找反白RE的部分)及除外符合(Exclude Match只不查找反白RE的部分)就留给各位大大试试啰。</p>
<p>　　当次描述用括号群组起来时，符合次描述的文字可用在之后的程序处理或RE本身。在预设的情型下，所符合的群组是由数字命名，由1开始，由顺序是由左至右，这自动群组命名，可在Expresso中的skeleton view或result view中看到。</p>
<p>　　Backreference是用来查找群组中抓取的符合文字所相同的文字。举例来说&rdquo;\1&rdquo;所指符合群组1所抓取的文字。</p>
<p>　　20. \b(\w+)\b\s*\1\b (寻找重复字，此处说的重复是指同样的字，中间有空白隔开如dog dog这样的字)<br />(\w+)会抓取至少一个字符的字母或数字的字，并将它命名为群组1，之后是查找任意空格符，再接和群组1相同的文字。</p>
<p>　　如果不喜欢群组自动命名的1，也可以自行命名，以上述例子为例，(\w+)改写为(?&lt;Word&gt;\w+)，这就是将所抓取的群组命名为Word，Backreference就要改写成为\k&lt;Word&gt;<br /><br />21. \b(?&lt;Word&gt;\w+)\b\s*\k&lt;Word&gt;\b (使用自行命名群组抓取重复字)</p>
<p>　　使用括号还有许多特别的语法元素，比较通用的列表如下：</p>
<p>　　抓取(Captures) <br />　　(exp) 符合exp并抓取它进自动命名的群组<br />　　(?&lt;name&gt;exp) 符合exp并抓取它进命名的群组name<br />　　(?:exp) 符合exp，不抓取它<br />　　Lookarounds <br />　　(?=exp) 符合字尾为exp的文字<br />　　(?&lt;=exp) 符合前缀为exp的文字<br />　　(?!exp) 符合后面没接exp字尾的文字<br />　　(?&lt;!exp) 符合前面没接exp前缀的文字<br />　　批注Comment <br />　　(?#comment) 批注</p>
<p>　　Positive Lookaround</p>
<p>　　接下来要谈的是lookahead及lookbehind assertions。它们所查找的是目前符合之前或之后的文字，并不包含目前符合本身。这些就如同&rdquo;^&rdquo;及&rdquo;\b&rdquo;特殊字符，本身并不会对应任何文字(用来界定位置)，也因此称做是zero-width assertions，看些例子也许会清楚些。</p>
<p>　　(?=exp)是一个&rdquo;zero-width positive lookahead assertion&rdquo;。它指的就是符合字尾为exp的文字，但不包含exp本身。</p>
<p>　　22. \b\w+(?=ing\b) (字尾为ing的字，比如说filling所符合的就是fill)<br />(?&lt;=exp)是一个&rdquo;zero-width positive lookbehind assertion&rdquo;。它指的就是符合前缀为exp的文字，但不包含exp本身。</p>
<p>　　23. (?&lt;=\bre)\w+\b (前缀为re的字，比如说repeated所符合的就是peated)<br />　　24. (?&lt;=\d)\d{3}\b (在字尾的三位数字，且之前接一位数字)<br />　　25. (?&lt;=\s)\w+(?=\s) (由空格符分隔开的字母数字字符串)</p>
<p>　　Negative Lookaround</p>
<p>　　之前有提到，如何查找一个非特定或非在特定群组的字符。但如果只是要验证某字符不存在而不要对应这些字符进来呢?举个例子来说，假设要查找一个字，它的字母里有q但接下来的字母不是u，可以用下列的RE来做。</p>
<p>　　26. \b\w*q[^u]\w*\b (一个字，其字母里有q但接下来的字母不是u)</p>
<p>　　这样的RE会有一个问题，因为[^u]要对应一个字符，所以若q是字的最后一个字母，[^u]这样的下法就会将空格符对应下去，结果就有可能会符合二个字，比如说&rdquo;Iraq haha&rdquo;这样的文字。使用Negative Lookaround就能解决这样的问题。</p>
<p>　　27. \b\w*q(?!u)\w*\b (一个字，其字母里有q但接下来的字母不是u)<br />　　这是&rdquo;zero-width negative lookahead assertion&rdquo;。</p>
<p>　　28. \d{3}(?!\d) (三个位的数字，其后不接一个位数字)</p>
<p>　　同样的，可以使用(?&lt;!exp)，&rdquo;zero-width negative lookbehind assertion&rdquo;，来符合前面没接exp前缀的文字符串。</p>
<p>　　29. (?&lt;![a-z ])\w{7} (七个字母数字的字符串，其前面没接字母或空格)</p>
<p>　　30. (?&lt;=&lt;(\w+)&gt;).*(?=&lt;\/\1&gt;) (HTML卷标间的文字)<br />　　这使用lookahead及lookbehind assertion来取出HTML间的文字，不包括HTML卷标。</p>
<p>　　请批注(Comments Please)<br />　　括号还有个特殊的用途就是用来包住批注，语法为&rdquo;(?#comment)&rdquo;，若设定&rdquo;Ignore Pattern Whitespace&rdquo;选项，则RE中的空格符当RE使用时会乎略。此选项设定时，&rdquo;#&rdquo;之后的文字会乎略。</p>
<p>　　31. HTML卷标间的文字，加上批注</p>
<p>　　(?&lt;=&nbsp; 　#查找前缀，但不包含它<br />　　&lt;(\w+)&gt; #HTML标签<br />　　)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #结束查找前缀<br />　　.*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #符合任何文字<br />　　(?=&nbsp;&nbsp;&nbsp;&nbsp; #查找字尾，但不包含它<br />　　&lt;\/\1&gt;&nbsp; #符合所抓取群组1之字符串，也就是前面小括号的HTML标签<br />　　)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #结束查找字尾</p>
<p>　　寻找最多字符的字及最少字符的字(Greedy and Lazy)<br />　　当RE下要查找一个范围的重复时(如&rdquo;.*&rdquo;)，它通常会寻找最多字符的符合字，也就是Greedy matching。举例来说。</p>
<p>　　32. a.*b&nbsp; (开始为a结束为b的最多字符的符合字)</p>
<p>　　若有一字符串是&rdquo;aabab&rdquo;，使用上述RE所得到的符合字符串就是&rdquo;aabab&rdquo;，因为这是寻找最多字符的字。有时希望是符合最少字符的字也就是lazy matching。只要将重复前述项目的表加上问号(?)就可以把它们全部变成lazy matching。因此&rdquo;*?&rdquo;代表的就是重复任意次数，但是使用最少重复的次数来符合。举个例子来说：</p>
<p>　　33. a.*?b (开始为a结束为b的最少字符的符合字)</p>
<p>　　若有一字符串是&rdquo;aabab&rdquo;，使用上述RE第一个所得到的符合字符串就是&rdquo;aab&rdquo;再来是&rdquo;ab&rdquo;，因为这是寻找最少字符的字。</p>
<p>　　*? 重复任意次数，最少重复次数为原则<br />　　+? 重复至少一次，最少重复次数为原则<br />　　?? 重复零次或一次，最少重复次数为原则<br />　　{n,m}? 重复至少n次，但不超过m次，最少重复次数为原则<br />　　{n,}? 重复至少n次，最少重复次数为原则<br /><br /></p>
<p>　　还有什么没提到呢?</p>
<p>　　到目前为止，已经提到了许多建立RE的元素，当然还有许多元素没有提到，下表整理了一些没提到的元素，在最左边的字段的数字是说明在Expresso中的例子。</p>
<p>　　# 语法 说明</p>
<p>　　\a Bell 字符<br />　　\b 通常是指字的边界，在字符组里所代表的就是backspace<br />　　\t Tab</p>
<p>　　34 \r Carriage return</p>
<p>　　\v Vertical Tab<br />　　\f From feed</p>
<p>　　35 \n New line<br />&nbsp;　　\e Escape</p>
<p>　　36 \nnn ASCII八位码为nnn的字符</p>
<p>　　37 \xnn 十六位码为nn的字符</p>
<p>　　38 \unnnn Unicode为nnnn的字符</p>
<p>　　39 \cN Control N字符，举例来说Ctrl-M是\cM</p>
<p>　　40 \A 字符串的开始(和^相似，但不需籍由multiline选项)</p>
<p>　　41 \Z 字符串的结尾<br />　　\z 字符串的结尾</p>
<p>　　42 \G 目前查找的开始</p>
<p>　　43 \p{name} Unicode 字符组名称为name的字符，比如说\p{Lowercase_Letter} 所指的就是小写字<br />　　(?&gt;exp) Greedy次描述，又称之为non-backtracking次描述。这只符合一次且不采backtracking。</p>
<p>　　44 (?&lt;x&gt;-&lt;y&gt;exp)</p>
<p>　　or (?-&lt;y&gt;exp) 平衡群组。虽复杂但好用。它让已命名的抓取群组可以在堆栈中操作使用。(小弟对这个也是不太懂哩)</p>
<p>　　45 (?im-nsx:exp) 为次描述exp更改RE选项，比如(?-i:Elvis)就是把Elvis大乎略大小写的选项关掉</p>
<p>　　46 (?im-nsx) 为之后的群组更改RE选项。<br />　　(?(exp)yes|no) 次描述exp视为zero-width positive lookahead。若此时有符合，则yes次描述为下一个符合标的，若否，则no 次描述为下一个符合标的。<br />　　(?(exp)yes) 和上述相同但无no次描述<br />　　(?(name)yes|no) 若name群组为有效群组名称，则yes次描述为下一个符合标的，若否，则no 次描述为下一个符合标的。</p>
<p>　　47 (?(name)yes) 和上述相同但无no次描述</p>
<h4>　　结论</h4>
<p>　　经过了一连串的例子，及Expresso的帮忙，相信各位大大对RE有个基本的了解，网络上当然有许多有关于RE的文章，如果各位大大有兴趣<a href="http://www.codeproject.com/"><font color="#002c99">http://www.codeproject.com</font></a> 还有许多关于RE的相关文章。若大大对书有兴趣的话，Jeffrey Friedl的Mastering Regular Expressions很多大大都有推(小弟还没拜读)。希望籍由这样的心得报告，能让对RE有兴趣的大大能缩短学习曲线，当然这是小弟第一次接触RE，若文章中有什么错误或说明的不好的地方，可要请各位大大体谅，并请各位大大将需要修正的地方mail给小弟，小弟会非常感谢各位大大。</p>
<p><br /><br /></p>
</font></strong></p><img src ="http://www.blogjava.net/jackylpz/aggbug/42846.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jackylpz/" target="_blank">过年</a> 2006-04-24 16:36 <a href="http://www.blogjava.net/jackylpz/archive/2006/04/24/42846.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA正则表达式4种常用功能</title><link>http://www.blogjava.net/jackylpz/archive/2006/04/24/42844.html</link><dc:creator>过年</dc:creator><author>过年</author><pubDate>Mon, 24 Apr 2006 08:31:00 GMT</pubDate><guid>http://www.blogjava.net/jackylpz/archive/2006/04/24/42844.html</guid><wfw:comment>http://www.blogjava.net/jackylpz/comments/42844.html</wfw:comment><comments>http://www.blogjava.net/jackylpz/archive/2006/04/24/42844.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jackylpz/comments/commentRss/42844.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jackylpz/services/trackbacks/42844.html</trackback:ping><description><![CDATA[<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td>
            <table cellspacing="0" cellpadding="0" width="100%" bgcolor="#ffffff" border="0">
                <tbody>
                    <tr>
                        <td class="title1" align="center" width="100%" bgcolor="#eeeeee" colspan="3" height="40"><strong>JAVA正则表达式4种常用功能</strong></td>
                    </tr>
                    <tr>
                        <td align="center" width="100%" bgcolor="#eeeeee">&nbsp;</td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
        <!-- end of article title -->
        <tr>
            <td valign="top" align="center" width="100%"><!--start of article content -->
            <table width="98%" border="0">
                <tbody>
                    <tr>
                        <td class="text" align="left" width="100%"><br />JAVA正则表达式4种常用功能&nbsp;<br />　　&nbsp;<br />　　正则表达式在字符串处理上有着强大的功能，sun在jdk1.4加入了对它的支持&nbsp;<br />　<br />　　下面简单的说下它的4种常用功能：<br />　　<br />　　查询：<br />　　<br />以下是代码片段：<br />&nbsp;String&nbsp;str=&quot;abc&nbsp;efg&nbsp;ABC&quot;;&nbsp;<br />&nbsp;<br />String&nbsp;regEx=&quot;a|f&quot;;&nbsp;//表示a或f&nbsp;<br />&nbsp;<br />&nbsp;Pattern&nbsp;p=Pattern.compile(regEx);&nbsp;<br />&nbsp;<br />&nbsp;Matcher&nbsp;m=p.matcher(str);&nbsp;<br />&nbsp;<br />&nbsp;boolean&nbsp;rs=m.find();&nbsp;<br /><br />　　<br />　　如果str中有regEx，那么rs为true，否则为flase。如果想在查找时忽略大小写，则可以写成Pattern&nbsp;p=Pattern.compile(regEx,Pattern.CASE_INSENSITIVE);<br />　　<br />　　提取：<br />以下是代码片段：<br />&nbsp;String&nbsp;regEx=&quot;.+\(.+)$&quot;;&nbsp;<br />&nbsp;<br />String&nbsp;str=&quot;c:\dir1\dir2\name.txt&quot;;&nbsp;<br />&nbsp;<br />&nbsp;Pattern&nbsp;p=Pattern.compile(regEx);&nbsp;<br />&nbsp;<br />&nbsp;Matcher&nbsp;m=p.matcher(str);&nbsp;<br />&nbsp;<br />&nbsp;boolean&nbsp;rs=m.find();&nbsp;<br />&nbsp;<br />&nbsp;for(int&nbsp;i=1;i&lt;=m.groupCount();i++){&nbsp;<br />&nbsp;<br />&nbsp;System.out.println(m.group(i));&nbsp;<br />&nbsp;<br />&nbsp;}&nbsp;<br /><br />　　<br />　　以上的执行结果为name.txt，提取的字符串储存在m.group(i)中，其中i最大值为m.groupCount();<br />　　<br />　　分割：<br />　　<br />以下是代码片段：<br />String&nbsp;regEx=&quot;::&quot;;&nbsp;<br />&nbsp;<br />&nbsp;Pattern&nbsp;p=Pattern.compile(regEx);&nbsp;<br />&nbsp;<br />&nbsp;String[]&nbsp;r=p.split(&quot;xd::abc::cde&quot;);&nbsp;<br />&nbsp;<br />&nbsp;执行后，r就是{&quot;xd&quot;,&quot;abc&quot;,&quot;cde&quot;}，其实分割时还有跟简单的方法：&nbsp;<br />&nbsp;<br />&nbsp;String&nbsp;str=&quot;xd::abc::cde&quot;;&nbsp;<br />&nbsp;<br />&nbsp;String[]&nbsp;r=str.split(&quot;::&quot;);&nbsp;<br /><br />　　<br />　　替换（删除）：<br />　　<br />以下是代码片段：<br />&nbsp;String&nbsp;regEx=&quot;a+&quot;;&nbsp;//表示一个或多个a&nbsp;<br /><br />&nbsp;Pattern&nbsp;p=Pattern.compile(regEx);&nbsp;<br />&nbsp;<br />&nbsp;Matcher&nbsp;m=p.matcher(&quot;aaabbced&nbsp;a&nbsp;ccdeaa&quot;);&nbsp;<br />&nbsp;<br />&nbsp;String&nbsp;s=m.replaceAll(&quot;A&quot;);&nbsp;<br />　　<br />　　结果为&quot;Abbced&nbsp;A&nbsp;ccdeA&quot;<br />　　<br />　　如果写成空串，既可达到删除的功能，比如：<br />　　<br />String&nbsp;s=m.replaceAll(&quot;&quot;);<br />　　<br />　　结果为&quot;bbced&nbsp;ccde&quot;<br />　　<br />　　附：<br />　　<br />　\D&nbsp;等於&nbsp;[^0-9]&nbsp;非数字&nbsp;<br />　\s&nbsp;等於&nbsp;[&nbsp;\t\n\x0B\f&nbsp;]&nbsp;空白字元&nbsp;<br />　\S&nbsp;等於&nbsp;[^&nbsp;\t\n\x0B\f&nbsp;]&nbsp;非空白字元&nbsp;<br />　\w&nbsp;等於&nbsp;[a-zA-Z_0-9]&nbsp;数字或是英文字&nbsp;<br />　　\W&nbsp;等於&nbsp;[^a-zA-Z_0-9]&nbsp;非数字与英文字&nbsp;<br />　　<br />　　^&nbsp;表示每行的开头<br />　　$&nbsp;表示每行的结尾</td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table><img src ="http://www.blogjava.net/jackylpz/aggbug/42844.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jackylpz/" target="_blank">过年</a> 2006-04-24 16:31 <a href="http://www.blogjava.net/jackylpz/archive/2006/04/24/42844.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java正则表达式详解</title><link>http://www.blogjava.net/jackylpz/archive/2006/04/24/42814.html</link><dc:creator>过年</dc:creator><author>过年</author><pubDate>Mon, 24 Apr 2006 04:48:00 GMT</pubDate><guid>http://www.blogjava.net/jackylpz/archive/2006/04/24/42814.html</guid><wfw:comment>http://www.blogjava.net/jackylpz/comments/42814.html</wfw:comment><comments>http://www.blogjava.net/jackylpz/archive/2006/04/24/42814.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jackylpz/comments/commentRss/42814.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jackylpz/services/trackbacks/42814.html</trackback:ping><description><![CDATA[<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">如果你曾经用过Perl或任何其他内建正则表达式支持的语言，你一定知道用正则表达式处理文本和匹配模式是多么简单。如果你不熟悉这个术语，那么&ldquo;正则表达式&rdquo;（Regular Expression）就是一个字符构成的串，它定义了一个用来搜索匹配字符串的模式。 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">许多语言，包括Perl、PHP、Python、JavaScript和JScript，都支持用正则表达式处理文本，一些文本编辑器用正则表达式实现高级&ldquo;搜索-替换&rdquo;功能。那么Java又怎样呢？本文写作时，一个包含了用正则表达式进行文本处理的Java规范需求（Specification Request）已经得到认可，你可以期待在JDK的下一版本中看到它。 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">然而，如果现在就需要使用正则表达式，又该怎么办呢？你可以从Apache.org下载源代码开放的Jakarta-ORO库。本文接下来的内容先简要地介绍正则表达式的入门知识，然后以Jakarta-ORO API为例介绍如何使用正则表达式。 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><strong><font size="4">一、正则表达式基础知识</font></strong> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">我们先从简单的开始。假设你要搜索一个包含字符&ldquo;cat&rdquo;的字符串，搜索用的正则表达式就是&ldquo;cat&rdquo;。如果搜索对大小写不敏感，单词&ldquo;catalog&rdquo;、&ldquo;Catherine&rdquo;、&ldquo;sophisticated&rdquo;都可以匹配。也就是说： </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_a.jpg" border="0" alt="" /> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><strong>1.1 句点符号</strong> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">假设你在玩英文拼字游戏，想要找出三个字母的单词，而且这些单词必须以&ldquo;t&rdquo;字母开头，以&ldquo;n&rdquo;字母结束。另外，假设有一本英文字典，你可以用正则表达式搜索它的全部内容。要构造出这个正则表达式，你可以使用一个通配符&mdash;&mdash;句点符号&ldquo;.&rdquo;。这样，完整的表达式就是&ldquo;t.n&rdquo;，它匹配&ldquo;tan&rdquo;、&ldquo;ten&rdquo;、&ldquo;tin&rdquo;和&ldquo;ton&rdquo;，还匹配&ldquo;t#n&rdquo;、&ldquo;tpn&rdquo;甚至&ldquo;t n&rdquo;，还有其他许多无意义的组合。这是因为句点符号匹配所有字符，包括空格、Tab字符甚至换行符： </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_b.jpg" border="0" alt="" /> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><strong>1.2 方括号符号</strong> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">为了解决句点符号匹配范围过于广泛这一问题，你可以在方括号（&ldquo;[]&rdquo;）里面指定看来有意义的字符。此时，只有方括号里面指定的字符才参与匹配。也就是说，正则表达式&ldquo;t[aeio]n&rdquo;只匹配&ldquo;tan&rdquo;、&ldquo;Ten&rdquo;、&ldquo;tin&rdquo;和&ldquo;ton&rdquo;。但&ldquo;Toon&rdquo;不匹配，因为在方括号之内你只能匹配单个字符： </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_c.jpg" border="0" alt="" /></td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><strong>1.3 &ldquo;或&rdquo;符号</strong> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">如果除了上面匹配的所有单词之外，你还想要匹配&ldquo;toon&rdquo;，那么，你可以使用&ldquo;|&rdquo;操作符。&ldquo;|&rdquo;操作符的基本意义就是&ldquo;或&rdquo;运算。要匹配&ldquo;toon&rdquo;，使用&ldquo;t(a|e|i|o|oo)n&rdquo;正则表达式。这里不能使用方扩号，因为方括号只允许匹配单个字符；这里必须使用圆括号&ldquo;()&rdquo;。圆括号还可以用来分组，具体请参见后面介绍。 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_d.jpg" border="0" alt="" /> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><strong>1.4 表示匹配次数的符号</strong> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">表一显示了表示匹配次数的符号，这些符号用来确定紧靠该符号左边的符号出现的次数： </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">
            <p align="center"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4n.jpg" border="0" alt="" /></p>
            </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">假设我们要在文本文件中搜索美国的社会安全号码。这个号码的格式是999-99-9999。用来匹配它的正则表达式如图一所示。在正则表达式中，连字符（&ldquo;-&rdquo;）有着特殊的意义，它表示一个范围，比如从0到9。因此，匹配社会安全号码中的连字符号时，它的前面要加上一个转义字符&ldquo;\&rdquo;。 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">
            <p align="center"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4a.gif" border="0" alt="" /> </p>
            </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">
            <p align="center">图一：匹配所有123-12-1234形式的社会安全号码</p>
            </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">假设进行搜索的时候，你希望连字符号可以出现，也可以不出现&mdash;&mdash;即，999-99-9999和999999999都属于正确的格式。这时，你可以在连字符号后面加上&ldquo;？&rdquo;数量限定符号，如图二所示： </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">
            <p align="center"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4b.gif" border="0" alt="" /> </p>
            </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">
            <p align="center">图二：匹配所有123-12-1234和123121234形式的社会安全号码</p>
            </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">下面我们再来看另外一个例子。美国汽车牌照的一种格式是四个数字加上二个字母。它的正则表达式前面是数字部分&ldquo;[0-9]{4}&rdquo;，再加上字母部分&ldquo;[A-Z]{2}&rdquo;。图三显示了完整的正则表达式。 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">
            <p align="center"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4c.gif" border="0" alt="" /> </p>
            </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">
            <p align="center">图三：匹配典型的美国汽车牌照号码，如8836KV</p>
            </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">1.5 &ldquo;否&rdquo;符号 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">&ldquo;^&rdquo;符号称为&ldquo;否&rdquo;符号。如果用在方括号内，&ldquo;^&rdquo;表示不想要匹配的字符。例如，图四的正则表达式匹配所有单词，但以&ldquo;X&rdquo;字母开头的单词除外。 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">
            <p align="center"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4d.gif" border="0" alt="" /> </p>
            </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">
            <p align="center">图四：匹配所有单词，但&ldquo;X&rdquo;开头的除外</p>
            </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">1.6 圆括号和空白符号 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">假设要从格式为&ldquo;June 26, 1951&rdquo;的生日日期中提取出月份部分，用来匹配该日期的正则表达式可以如图五所示： </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">
            <p align="center"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4e.gif" border="0" alt="" /> </p>
            </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">
            <p align="center">图五：匹配所有Moth DD,YYYY格式的日期</p>
            </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">新出现的&ldquo;\s&rdquo;符号是空白符号，匹配所有的空白字符，包括Tab字符。如果字符串正确匹配，接下来如何提取出月份部分呢？只需在月份周围加上一个圆括号创建一个组，然后用ORO API（本文后面详细讨论）提取出它的值。修改后的正则表达式如图六所示： </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">
            <p align="center"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4f.gif" border="0" alt="" /> </p>
            </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">
            <p align="center">图六：匹配所有Month DD,YYYY格式的日期，定义月份值为第一个组</p>
            </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><strong>1.7 其它符号</strong> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">为简便起见，你可以使用一些为常见正则表达式创建的快捷符号。如表二所示： </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">表二：常用符号 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">
            <p align="center"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4o.jpg" border="0" alt="" /> </p>
            </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">例如，在前面社会安全号码的例子中，所有出现&ldquo;[0-9]&rdquo;的地方我们都可以使用&ldquo;\d&rdquo;。修改后的正则表达式如图七所示： </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">
            <p align="center"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4g.gif" border="0" alt="" /> </p>
            </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">
            <p align="center">图七：匹配所有123-12-1234格式的社会安全号码</p>
            </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><strong><font size="4">二、Jakarta-ORO库</font></strong> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">有许多源代码开放的正则表达式库可供Java程序员使用，而且它们中的许多支持Perl 5兼容的正则表达式语法。我在这里选用的是Jakarta-ORO正则表达式库，它是最全面的正则表达式API之一，而且它与Perl 5正则表达式完全兼容。另外，它也是优化得最好的API之一。 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">Jakarta-ORO库以前叫做OROMatcher，Daniel Savarese大方地把它赠送给了Jakarta Project。你可以按照本文最后参考资源的说明下载它。 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">我首先将简要介绍使用Jakarta-ORO库时你必须创建和访问的对象，然后介绍如何使用Jakarta-ORO API。 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><strong>▲ PatternCompiler对象</strong> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">首先，创建一个Perl5Compiler类的实例，并把它赋值给PatternCompiler接口对象。Perl5Compiler是PatternCompiler接口的一个实现，允许你把正则表达式编译成用来匹配的Pattern对象。 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_e.jpg" border="0" alt="" /> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><strong>▲ Pattern对象</strong> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">要把正则表达式编译成Pattern对象，调用compiler对象的compile()方法，并在调用参数中指定正则表达式。例如，你可以按照下面这种方式编译正则表达式&ldquo;t[aeio]n&rdquo;： </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_f.jpg" border="0" alt="" /> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">默认情况下，编译器创建一个大小写敏感的模式（pattern）。因此，上面代码编译得到的模式只匹配&ldquo;tin&rdquo;、&ldquo;tan&rdquo;、 &ldquo;ten&rdquo;和&ldquo;ton&rdquo;，但不匹配&ldquo;Tin&rdquo;和&ldquo;taN&rdquo;。要创建一个大小写不敏感的模式，你应该在调用编译器的时候指定一个额外的参数： </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_g.jpg" border="0" alt="" /> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">创建好Pattern对象之后，你就可以通过PatternMatcher类用该Pattern对象进行模式匹配。 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><strong>▲ PatternMatcher对象</strong> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">PatternMatcher对象根据Pattern对象和字符串进行匹配检查。你要实例化一个Perl5Matcher类并把结果赋值给PatternMatcher接口。Perl5Matcher类是PatternMatcher接口的一个实现，它根据Perl 5正则表达式语法进行模式匹配： </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_h.jpg" border="0" alt="" /> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">使用PatternMatcher对象，你可以用多个方法进行匹配操作，这些方法的第一个参数都是需要根据正则表达式进行匹配的字符串： </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">&middot; boolean matches(String input, Pattern pattern)：当输入字符串和正则表达式要精确匹配时使用。换句话说，正则表达式必须完整地描述输入字符串。 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">&middot; boolean matchesPrefix(String input, Pattern pattern)：当正则表达式匹配输入字符串起始部分时使用。 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">&middot; boolean contains(String input, Pattern pattern)：当正则表达式要匹配输入字符串的一部分时使用（即，它必须是一个子串）。 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">另外，在上面三个方法调用中，你还可以用PatternMatcherInput对象作为参数替代String对象；这时，你可以从字符串中最后一次匹配的位置开始继续进行匹配。当字符串可能有多个子串匹配给定的正则表达式时，用PatternMatcherInput对象作为参数就很有用了。用PatternMatcherInput对象作为参数替代String时，上述三个方法的语法如下： </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">&middot; boolean matches(PatternMatcherInput input, Pattern pattern) </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">&middot; boolean matchesPrefix(PatternMatcherInput input, Pattern pattern) </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">&middot; boolean contains(PatternMatcherInput input, Pattern pattern) </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><strong><font size="4">三、应用实例</font></strong> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">下面我们来看看Jakarta-ORO库的一些应用实例。 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><strong>3.1 日志文件处理</strong> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">任务：分析一个Web服务器日志文件，确定每一个用户花在网站上的时间。在典型的BEA WebLogic日志文件中，日志记录的格式如下： </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_i.jpg" border="0" alt="" /></td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">分析这个日志记录，可以发现，要从这个日志文件提取的内容有两项：IP地址和页面访问时间。你可以用分组符号（圆括号）从日志记录提取出IP地址和时间标记。 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">首先我们来看看IP地址。IP地址有4个字节构成，每一个字节的值在0到255之间，各个字节通过一个句点分隔。因此，IP地址中的每一个字节有至少一个、最多三个数字。图八显示了为IP地址编写的正则表达式： </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">
            <p align="center"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4h.gif" border="0" alt="" /> </p>
            </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">
            <p align="center">图八：匹配IP地址</p>
            </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">IP地址中的句点字符必须进行转义处理（前面加上&ldquo;\&rdquo;），因为IP地址中的句点具有它本来的含义，而不是采用正则表达式语法中的特殊含义。句点在正则表达式中的特殊含义本文前面已经介绍。 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">日志记录的时间部分由一对方括号包围。你可以按照如下思路提取出方括号里面的所有内容：首先搜索起始方括号字符（&ldquo;[&rdquo;），提取出所有不超过结束方括号字符（&ldquo;]&rdquo;）的内容，向前寻找直至找到结束方括号字符。图九显示了这部分的正则表达式。 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">
            <p align="center"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4i.gif" border="0" alt="" /> </p>
            </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">
            <p align="center">图九：匹配至少一个字符，直至找到&ldquo;]&rdquo;</p>
            </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">现在，把上述两个正则表达式加上分组符号（圆括号）后合并成单个表达式，这样就可以从日志记录提取出IP地址和时间。注意，为了匹配&ldquo;- -&rdquo;（但不提取它），正则表达式中间加入了&ldquo;\s-\s-\s&rdquo;。完整的正则表达式如图十所示。 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">
            <p align="center"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4j.gif" border="0" alt="" /> </p>
            </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">
            <p align="center">图十：匹配IP地址和时间标记</p>
            </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">现在正则表达式已经编写完毕，接下来可以编写使用正则表达式库的Java代码了。 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">为使用Jakarta-ORO库，首先创建正则表达式字符串和待分析的日志记录字符串： </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_j.jpg" border="0" alt="" /> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">这里使用的正则表达式与图十的正则表达式差不多完全相同，但有一点例外：在Java中，你必须对每一个向前的斜杠（&ldquo;\&rdquo;）进行转义处理。图十不是Java的表示形式，所以我们要在每个&ldquo;\&rdquo;前面加上一个&ldquo;\&rdquo;以免出现编译错误。遗憾的是，转义处理过程很容易出现错误，所以应该小心谨慎。你可以首先输入未经转义处理的正则表达式，然后从左到右依次把每一个&ldquo;\&rdquo;替换成&ldquo;\\&rdquo;。如果要复检，你可以试着把它输出到屏幕上。 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">初始化字符串之后，实例化PatternCompiler对象，用PatternCompiler编译正则表达式创建一个Pattern对象： </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_k.jpg" border="0" alt="" /> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">现在，创建PatternMatcher对象，调用PatternMatcher接口的contain()方法检查匹配情况： </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_l.jpg" border="0" alt="" /> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">接下来，利用PatternMatcher接口返回的MatchResult对象，输出匹配的组。由于logEntry字符串包含匹配的内容，你可以看到类如下面的输出： </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_m.jpg" border="0" alt="" /></td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><strong>3.2 HTML处理实例一</strong> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">下面一个任务是分析HTML页面内FONT标记的所有属性。HTML页面内典型的FONT标记如下所示： </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><font face="Arial, Serif" color="#ff0000" size="+2"></font><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_n.jpg" border="0" alt="" /> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">程序将按照如下形式，输出每一个FONT标记的属性： </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_o.jpg" border="0" alt="" /> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">在这种情况下，我建议你使用两个正则表达式。第一个如图十一所示，它从字体标记提取出&ldquo;&quot;face=&quot;Arial, Serif&quot; size=&quot;+2&quot; color=&quot;red&quot;&rdquo;。 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">
            <p align="center"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4k.gif" border="0" alt="" /> </p>
            </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">
            <p align="center">图十一：匹配FONT标记的所有属性</p>
            </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">第二个正则表达式如图十二所示，它把各个属性分割成名字-值对。 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">
            <p align="center"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4l.gif" border="0" alt="" /> </p>
            </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">
            <p align="center">图十二：匹配单个属性，并把它分割成名字-值对</p>
            </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">分割结果为： </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_p.jpg" border="0" alt="" /> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">现在我们来看看完成这个任务的Java代码。首先创建两个正则表达式字符串，用Perl5Compiler把它们编译成Pattern对象。编译正则表达式的时候，指定Perl5Compiler.CASE_INSENSITIVE_MASK选项，使得匹配操作不区分大小写。 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">接下来，创建一个执行匹配操作的Perl5Matcher对象。 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_q.jpg" border="0" alt="" /> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">假设有一个String类型的变量html，它代表了HTML文件中的一行内容。如果html字符串包含FONT标记，匹配器将返回true。此时，你可以用匹配器对象返回的MatchResult对象获得第一个组，它包含了FONT的所有属性： </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_r.jpg" border="0" alt="" /> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">接下来创建一个PatternMatcherInput对象。这个对象允许你从最后一次匹配的位置开始继续进行匹配操作，因此，它很适合于提取FONT标记内属性的名字-值对。创建PatternMatcherInput对象，以参数形式传入待匹配的字符串。然后，用匹配器实例提取出每一个FONT的属性。这通过指定PatternMatcherInput对象（而不是字符串对象）为参数，反复地调用PatternMatcher对象的contains()方法完成。PatternMatcherInput对象之中的每一次迭代将把它内部的指针向前移动，下一次检测将从前一次匹配位置的后面开始。 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">本例的输出结果如下： </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_s.jpg" border="0" alt="" /> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><strong>3.3 HTML处理实例二</strong> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">下面我们来看看另一个处理HTML的例子。这一次，我们假定Web服务器从widgets.acme.com移到了newserver.acme.com。现在你要修改一些页面中的链接： </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_t.jpg" border="0" alt="" /> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">执行这个搜索的正则表达式如图十三所示： </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">
            <p align="center"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4m.gif" border="0" alt="" /> </p>
            </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">
            <p align="center">图十三：匹配修改前的链接</p>
            </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">如果能够匹配这个正则表达式，你可以用下面的内容替换图十三的链接： </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><a href="http://newserver.acme.com/interface.html#$1"></a><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_u.jpg" border="0" alt="" /></td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">注意#字符的后面加上了$1。Perl正则表达式语法用$1、$2等表示已经匹配且提取出来的组。图十三的表达式把所有作为一个组匹配和提取出来的内容附加到链接的后面。 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">现在，返回Java。就象前面我们所做的那样，你必须创建测试字符串，创建把正则表达式编译到Pattern对象所必需的对象，以及创建一个PatternMatcher对象：<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_v.jpg" border="0" alt="" /> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">接下来，用com.oroinc.text.regex包Util类的substitute()静态方法进行替换，输出结果字符串： </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_w.jpg" border="0" alt="" /> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">Util.substitute()方法的语法如下： </td>
        </tr>
    </tbody>
</table>
<table height="17" width="620" align="center">
    <tbody>
        <tr>
            <td class="a14" height="13"><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_x.jpg" border="0" alt="" /> </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14">这个调用的前两个参数是以前创建的PatternMatcher和Pattern对象。第三个参数是一个Substiution对象，它决定了替换操作如何进行。本例使用的是Perl5Substitution对象，它能够进行Perl5风格的替换。第四个参数是想要进行替换操作的字符串，最后一个参数允许指定是否替换模式的所有匹配子串（Util.SUBSTITUTE_ALL），或只替换指定的次数。 </td>
        </tr>
    </tbody>
</table>
<table width="620" align="center">
    <tbody>
        <tr>
            <td class="a14"><strong>【结束语】</strong>在这篇文章中，我为你介绍了正则表达式的强大功能。只要正确运用，正则表达式能够在字符串提取和文本修改中起到很大的作用。另外，我还介绍了如何在Java程序中通过Jakarta-ORO库利用正则表达式。至于最终采用老式的字符串处理方式（使用StringTokenizer，charAt，和substring），还是采用正则表达式，这就有待你自己决定了。</td>
        </tr>
    </tbody>
</table><img src ="http://www.blogjava.net/jackylpz/aggbug/42814.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jackylpz/" target="_blank">过年</a> 2006-04-24 12:48 <a href="http://www.blogjava.net/jackylpz/archive/2006/04/24/42814.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java源代码分析----jvm.dll装载过程</title><link>http://www.blogjava.net/jackylpz/archive/2006/04/22/42546.html</link><dc:creator>过年</dc:creator><author>过年</author><pubDate>Sat, 22 Apr 2006 13:50:00 GMT</pubDate><guid>http://www.blogjava.net/jackylpz/archive/2006/04/22/42546.html</guid><wfw:comment>http://www.blogjava.net/jackylpz/comments/42546.html</wfw:comment><comments>http://www.blogjava.net/jackylpz/archive/2006/04/22/42546.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jackylpz/comments/commentRss/42546.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jackylpz/services/trackbacks/42546.html</trackback:ping><description><![CDATA[<strong>简述<br /></strong>　　<br />　　众所周知java.exe是java class文件的执行程序，但实际上java.exe程序只是<br />　　一个执行的外壳，它会装载jvm.dll（windows下，以下皆以windows平台为例，<br />　　linux下和solaris下其实类似，为：libjvm.so），这个动态连接库才是java<br />　　虚拟机的实际操作处理所在。本文探究java.exe程序是如何查找和装载jvm.dll<br />　　动态库，并调用它进行class文件执行处理的。<br />　　<br />　　<strong>源代码</strong><br />　　<br />　　本文分析之代码，《JavaTM 2 SDK, Standard Edition, v1.4.2 fcs<br />　　Community Source Release》，可从sun官方网站下载，主要分析的源代码为：<br />　　j2se\src\share\bin\java.c<br />　　j2se\src\windows\bin\java_md.c<br />　　<br />　　<strong>java.c是什么东西</strong><br />　　<br />　　&lsquo;java程序&rsquo;源代码<br />　　所谓&lsquo;java程序&rsquo;，包括jdk中的java.exe\javac.exe\javadoc.exe，java.c源<br />　　代码中通过JAVA_ARGS宏来控制生成的代码，如果该宏没定义则编译文件控制生<br />　　成java.exe否则编译文件控制生成其他的&lsquo;java程序&rsquo;。<br />　　比如：<br />　　j2se\make\java\javac\Makefile（这是javac编译文件）中：<br />　　$(CD) ../../sun/javac ; $(MAKE) $@ RELEASE=$(RELEASE) FULL_VERSION=$(FULL_VERSION)<br />　　j2se\make\sun\javac\javac\Makefile（由上面Makefile文件调用）中：<br />　　JAVA_ARGS = &quot;{ \&quot;-J-ms8m\&quot;, \&quot;com.sun.tools.javac.Main\&quot; }&quot;<br />　　则由同一份java.c代码生成的javac.exe程序就会直接调用java类方法：<br />　　com.sun.tools.javac.Main，这样使其执行起来就像是直接运行的一个exe文件，<br />　　而未定义JAVA_ARGS的java.exe程序则会调用传递过来参数中的类方法。<br />　　<br />　　<strong>从java.c的main入口函数说起</strong><br />　　<br />　　main()函数中前面一段为重新分配参数指针的处理。<br />　　然后调用函数：CreateExecutionEnvironment，该函数主要查找java运行环境的<br />　　目录，和jvm.dll这个虚拟机核心动态连接库文件路径所在。根据操作系统不同，<br />　　该函数有不同实现版本，但大体处理逻辑相同，我们看看windows平台该函数的处<br />　　理（j2se\src\windows\bin\java_md.c）。<br />　　<br />　　CreateExecutionEnvironment函数主要分为三步处理：<br />　　a、查找jre路径。<br />　　b、装载jvm.cfg中指定的虚拟机动态连接库（jvm.dll）参数。<br />　　c、取jvm.dll文件路径。<br />　　<br />　　<strong>实现：</strong><br />　　<br />　　a、查找jre路径是通过java_md.c中函数：GetJREPath实现的。<br />　　该函数首先调用GetApplicationHome函数，GetApplicationHome函数调用windows<br />　　API函数GetModuleFileName取java.exe程序的绝对路径，以我的jdk安装路径为例，<br />　　为：&ldquo;D:\java\j2sdk1.4.2_04\bin\java.exe&rdquo;，然后去掉文件名取绝对路径为：<br />　　&ldquo;D:\java\j2sdk1.4.2_04\bin&rdquo;，之后会在去掉最后一级目录，现在绝对路径为：<br />　　&ldquo;D:\java\j2sdk1.4.2_04&rdquo;。<br />　　然后GetJREPath函数继续判断刚刚取的路径+\bin\java.dll组合成的这个java.dll<br />　　文件是否存在，如果存在则&ldquo;D:\java\j2sdk1.4.2_04&rdquo;为JRE路径，否则判断取得<br />　　的&ldquo;D:\java\j2sdk1.4.2_04&rdquo;路径+\jre\bin\java.dll文件是否存在，存在则<br />　　&ldquo;D:\java\j2sdk1.4.2_04\jre&rdquo;为JRE路径。如果上面两种情况都不存在，则从注<br />　　册表中去查找（参见函数GetPublicJREHome）。<br />　　<br />　　<strong>函数：GetPublicJREHome先查找</strong><br />　　HKEY_LOCAL_MACHINE\Software\JavaSoft\Java Runtime Environment\CurrentVersion<br />　　键值&ldquo;当前JRE版本号&rdquo;，判断&ldquo;当前JRE版本号&rdquo;是否为1.4做为版本号，如果是则<br />　　取HKEY_LOCAL_MACHINE\Software\JavaSoft\Java Runtime Environment\&ldquo;当前JRE版本号&rdquo;<br />　　\JavaHome的路径所在为JRE路径。<br />　　<br />　　我的JDK返回的JRE路径为：&ldquo;D:\java\j2sdk1.4.2_04\jre&rdquo;。<br />　　<br />　　b、装载jvm.cfg虚拟机动态连接库配置文件是通过java.c中函数:ReadKnownVMs实现<br />　　的。<br />　　该函数首先组合jvm.cfg文件的绝对路径，JRE路径+\lib+\ARCH（CPU构架）+\jvm.cfg<br />　　ARCH（CPU构架）的判断是通过java_md.c中GetArch函数判断的，该函数中windows平<br />　　台只有两种情况：WIN64的&lsquo;ia64&rsquo;，其他情况都为&lsquo;i386&rsquo;。我的为i386所以jvm.cfg<br />　　文件绝对路径为：&ldquo;D:\java\j2sdk1.4.2_04\jre\lib\i386\jvm.cfg&rdquo;。文件内容如<br />　　下：<br />　　## @(#)jvm.cfg　 1.7 03/01/23# # Copyright 2003 Sun Microsystems, Inc. All rights reserved.# SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.# # ### List of JVMs that can be used as an option to java, javac, etc.# Order is important -- first in this list is the default JVM.# NOTE that this both this file and its format are UNSUPPORTED and# WILL GO AWAY in a future release.## You may also select a JVM in an arbitrary location with the# &quot;-XXaltjvm=&lt;jvm_dir&gt;&quot; option, but that too is unsupported# and may not be available in a future release.#-client KNOWN-server KNOWN-hotspot ALIASED_TO -client-classic WARN-native ERROR-green ERROR<br />　　<br />　　（如果细心的话，我们会发现在JDK目录中我的为：&ldquo;D:\java\j2sdk1.4.2_04\jre\bin\client&rdquo;和&ldquo;D:\java\j2sdk1.4.2_04\jre\bin\server&rdquo;两个目录下都存在jvm.dll文件。而java正是通过jvm.cfg配置文件来管理这些不同版本的jvm.dll的。）<br />　　<br />　　ReadKnownVMs函数会将该文件中的配置内容读入到一个JVM配置结构的全局变量中，该函数首先跳过注释（以&lsquo;#&rsquo;开始的行），然后读取以&lsquo;-&rsquo;开始的行指定的jvm参数，每一行为一个jvm信息，第一部分为jvm虚拟机名称，第二部分为配置参数，比如行：<br />　　&ldquo;-client KNOWN&rdquo;则&ldquo;-client&rdquo;为虚拟机名称，而&ldquo;KNOWN&rdquo;为配置类型参数，&ldquo;KNOWN&rdquo;<br />　　表示该虚拟机的jvm.dll存在，而&ldquo;ALIASED_TO&rdquo;表示为另一个jvm.dll的别名，&ldquo;WARN&rdquo;<br />　　表示该虚拟机的jvm.dll不存在但运行时会用其他存在的jvm.dll替代执行，而&ldquo;ERROR&rdquo;<br />　　同样表示该类虚拟机的jvm.dll不存在且运行时不会找存在的jvm.dll替代而直接抛出错误<br />　　信息。<br />　　<br />　　在运行java程序时指定使用那个虚拟机的判断是由java.c中函数：CheckJvmType判断，该函数会检查java运行参数中是否有指定jvm的参数，然后从ReadKnownVMs函数读取的jvm.cfg数据结构中去查找，从而指定不同的jvm类型（最终导致装载不同jvm.dll）。有两种方法可以指定jvm类型，一种按照jvm.cfg文件中的jvm名称指定，第二种方法是直接指定，它们执行的方法分别是&ldquo;java -J&lt;jvm.cfg中jvm名称&gt;&rdquo;、&ldquo;java -XXaltjvm=&lt;jvm类型名称&gt;&rdquo;或&ldquo;java -J-XXaltjvm=&lt;jvm类型名称&gt;&rdquo;。如果是第一种参数传递方式，CheckJvmType函数会取参数&lsquo;-J&rsquo;后面的jvm名称，然后从已知的jvm配置参数中查找如果找到同名的则去掉该jvm名称前的&lsquo;-&rsquo;直接返回该值；而第二种方法，会直接返回&ldquo;-XXaltjvm=&rdquo;或&ldquo;-J-XXaltjvm=&rdquo;后面的jvm类型名称；如果在运行java时未指定上面两种方法中的任一一种参数，CheckJvmType会取配置文件中第一个配置中的jvm名称，去掉名称前面的&lsquo;-&rsquo;返回该值。CheckJvmType函数的这个返回值会在下面的函数中汇同jre路径组合成jvm.dll的绝对路径。<br />　　<br />　　比如：如果在运行java程序时使用&ldquo;java -J-client test&rdquo;则ReadKnownVMs会读取参数&ldquo;-client&rdquo;然后查找jvm.cfg读入的参数中是否有jvm名称为&ldquo;-client&rdquo;的，如果有则去掉jvm名称前的&ldquo;-&rdquo;直接返回&ldquo;client&rdquo;；而如果在运行java程序时使用如下参数：<br />　　&ldquo;java -XXaltjvm=D:\java\j2sdk1.4.2_04\jre\bin\client test&rdquo;，则ReadKnownVMs<br />　　会直接返回&ldquo;D:\java\j2sdk1.4.2_04\jre\bin\client&rdquo;；如果不带上面参数执行如：<br />　　&ldquo;java test&rdquo;，因为在jvm.cfg配置文件中第一个存在的jvm为&ldquo;-client&rdquo;，所以函数<br />　　ReadKnownVMs也会去掉jvm名称前的&ldquo;-&rdquo;返回&ldquo;client&rdquo;。其实这三中情况都是使用的<br />　　&ldquo;D:\java\j2sdk1.4.2_04\jre\bin\client\jvm.dll&rdquo;这个jvm动态连接库处理test这个class的，见下面GetJVMPath函数。<br />　　<br />　　c、取jvm.dll文件路径是通过java_md.c中函数：GetJVMPath实现的。<br />　　由上面两步我们已经获得了JRE路径和jvm的类型字符串。GetJVMPath函数判断CheckJvmType<br />　　返回的jvm类型字符串中是否包含了&lsquo;\&rsquo;或&lsquo;/&rsquo;如果包含则以该jvm类型字符串+\jvm.dll作为JVM的全路径，否则以JRE路径+\bin+\jvm类型字符串+\jvm.dll作为JVM的全路径。<br />　　<br />　　看看上面的例子，第一种情况&ldquo;java -J-client test&rdquo;jvm.dll路径为：<br />　　JRE路径+\bin+\jvm类型字符串+\jvm.dll 按照我的JDK路径则为：<br />　　&ldquo;D:\java\j2sdk1.4.2_04\jre&rdquo;+&ldquo;\bin&rdquo;+&ldquo;\client&rdquo;+&ldquo;\jvm.dll&rdquo;。<br />　　第二种情况&ldquo;java -XXaltjvm=D:\java\j2sdk1.4.2_04\jre\bin\client test&rdquo;路径为：<br />　　jvm类型字符串+\jvm.dll即为：&ldquo;D:\java\j2sdk1.4.2_04\jre\bin\client&rdquo;+&ldquo;\jvm.dll&rdquo;<br />　　第三种情况&ldquo;java test&rdquo;为：&ldquo;D:\java\j2sdk1.4.2_04\jre&rdquo;+&ldquo;\bin&rdquo;+&ldquo;\client&rdquo;<br />　　+&ldquo;\jvm.dll&rdquo;与情况一相同。所以这三种情况都是调用的jvm动态连接库&ldquo;D:\javaj2sdk1.4.2_04\jre\bin\client\jvm.dll&rdquo;处理test类的。<br />　　<br />　　我们来进一步验证一下：<br />　　打开cmd控制台：<br />　　<br />　　设置java装载调试<br />　　E:\work\java_research&gt;set _JAVA_LAUNCHER_DEBUG=1<br />　　<br />　　情况一<br />　　E:\work\java_research&gt;java -J-client test.ScanDirectory<br />　　----_JAVA_LAUNCHER_DEBUG----<br /><br /><img src ="http://www.blogjava.net/jackylpz/aggbug/42546.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jackylpz/" target="_blank">过年</a> 2006-04-22 21:50 <a href="http://www.blogjava.net/jackylpz/archive/2006/04/22/42546.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基于Java的操作系统发展史！</title><link>http://www.blogjava.net/jackylpz/archive/2006/04/07/39749.html</link><dc:creator>过年</dc:creator><author>过年</author><pubDate>Fri, 07 Apr 2006 02:32:00 GMT</pubDate><guid>http://www.blogjava.net/jackylpz/archive/2006/04/07/39749.html</guid><wfw:comment>http://www.blogjava.net/jackylpz/comments/39749.html</wfw:comment><comments>http://www.blogjava.net/jackylpz/archive/2006/04/07/39749.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/jackylpz/comments/commentRss/39749.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jackylpz/services/trackbacks/39749.html</trackback:ping><description><![CDATA[<span class="tpc_content">转自:http://blog.csdn.net/fasttalk/archive/2005/02/08/284637.aspx <br /><br />纯Java操作系统SavaJe已经得到广泛支持与商业应用 <br />2005年 02月05日 <br /><br /><br />贝尔实验室发明的SavaJe OS是一个纯Java操作系统，支持J2SE，已经得到强大的商业支持，LG已经采用了SavaJe做为其3G手机 <br /><br />SavaJe OS, an open standards-based, 100% pure Java platform for mobile phones <br />全文：http://www.savaje.com/ <br /><br />SavaJe有着优良的血统： <br />来自朗讯贝尔实验室 <br />Lucent Technologies launches new venture, savaJe&trade; technologies, first company to offer full Java&trade; 2&trade; support for exploding information appliance market <br />下面的链接有详细的介绍： <br />http://www.lucent.com/press/0600/000606.coa.html <br /><br /><br /><br />贝尔实验室总能给这个世界带来划时代的发明： <br /><br />C语言、C++、UNIX、电话、有声电影、电报、晶体管、激光器、太阳能电池、发光二极管、数字交换机、通讯卫星、电脑、手机、通讯网......... <br /><br /><br />天哪！ <br /><br />那么SavaJe............ <br /><br /><br /><br />有关SavaJe还有些事要说：SavaJe已经是一个非常成熟的操作系统了，它利用的是支持bytecode的ARM CPU（ARM CPU占嵌入CPU市场的８０％市场份额），而且SavaJe支持的是J2SE： <br /><br /><br />该公司说，SavaJe XE OS是第一个支持Java 2 Platform, Standard Edition（J2SE，标准版）的小型上网设备操作系统。实际上，该领域中原来所有的Java支持都是支持Java 2 Platform, Micro Edition（J2ME，微型版本）。 <br />http://www.pday.com.cn/news/2001/2001-09/092622.htm <br /><br /><br /><br /><br />SavaJe XE为下一代信息电器带来J2SE <br />无线Handheld的OS越来越多地渗入Java，现在J2ME、PersonalJava已经出现在各种手持设备包括PocketPC和Palm上，但是很多人仍然认为J2SE(标准版)并没有能直接用于各种IA，直到SavaJe XE OS的出现！ <br /><br />Sun网站上一篇文章详细讨论了SavaJe XE OS，这个Java平台不单单是一个虚拟机(VM)，而且是一个真正的32位、多任务、多线程的OS！这是真正的J2SE的Handheld版本！ <br /><br />SavaJe的CEO George Grey认为，SavaJe XE有两大优势，其一是J2SE已经有相当的开发者和应用，其二是他们选择了ARM的硬件平台，StrongARM已经占据嵌入CPU市场77%的份额。 <br />http://telecom.km169.net/data/200202/2610273001.htm <br /><br /><br /><br /><br /><br />SavaJe是几个世界级大公司沃达丰、Orange和T-Mobile注资的公司，有强硬的后台，前景应该不差。既然沃达丰、Orange和T-Mobile共同出资SavaJe，相信这几个公司的手机中有相当大比例是用SavaJe： <br /><br /><br /><br /><br />运营商与手机厂商的大战会上演吗？ <br /><br />6月底，沃达丰联合世界顶级运营商mmO2、NTT DoCoMo、Orange、TIM、T-Mobile和Telefonica等秘密聚会，接着抛出了一个名为OMTP（开放移动终端平台）的组织，最引人瞩目的是其对待设备商和运营商的不平等准入规则。 <br /><br />OMTP 成立受益最大的将是一家正处于谣言漩涡中的小公司&mdash;&mdash;SavaJe，这家由沃达丰、Orange和T-Mobile注资的公司以推出完全可定制的基于 Java的手机操作系统而闻名。值得注意的是，在OMTP成立的同时，几家运营商都宣布了增资该公司的新闻。运营商是否要借SavaJe给手机厂商施压？ <br />http://www.tele.com.cn/article/list.asp?id=2586 <br /><br /><br /><br /><br /><br /><br /><br />LG 5月份手机销量创纪录 <br /><br />　　LG电子公司虽然是已经竞争相当激烈的手机市场上的新军，但其表示，今年5月份的手机销量创下新纪录，主要是出货给和记黄埔公司的手机数量增加。根据 Gartner研究公司的数据显示，LG是全球第六大手机制造商，上个月销售出了320万部手机，较之4月份增加4.9%，较之去年同期猛增了 98.4%。 <br />http://www.comm9.com/sfnews/ztbd/200471313331.htm <br /><br /><br /><br /><br /><br /><br /><br />(BW)LG电子选择SavaJe的操作系统应用于下一代手机 <br /><br />SavaJe与LG电子的伙伴关系给营运商带来新机遇，给消费者带来新体验 <br />LG电子以及SavaJe Technologies今天宣布双方的合作关系，从2005年开始将会把SavaJe OS(TM)（SavaJe 操作系统(TM)）应用于2.5以及3G手机。不同于其他的手机操作系统，SavaJe OS提供完整的Java(R)环境，为营运商、开发商以及他们的客户提供最为丰富、最具创新性以及最安全的使用体验。详情将会在即将于明年2月在戛纳召开的3GSM世界大会上提供。 <br />http://www.wx800.com/msg/2004/12/09/d71713.php <br /><br /><br /><br /><br /><br /><br />　　日前，沃达丰、Orange与日本NTT DoCoMo等世界顶级的移动运营商在伦敦建立了一个国际联盟，以驾驭未来的手机发展方向，并推动手机游戏、视频等多方面的增值业务。 <br />因为运营商一直担心手机操作系统被微软和诺基亚投资的Symbian所垄断。该联盟已经启动了与Savaje Technologies公司的谈判，该公司股东包括沃达丰与Orange，主要致力于开发开放式手机操作系统。 <br />http://www.comm9.com/sfnews/ztbd/200471313331.htm <br /><br /><br /><br /><br /><br /><br /><br />另外从作为信息家电设备发展平台的角度来看，一个简单且可跨各式CPU平台的操作系统，也是解决作法之一，JavaOS就是一个这样的典型方案。目前例如像 SavaJe公司所发展，预计于今年九月推出的SavaJe XE操作系统，就是一个可作为在12MB内存、32MB RAM、190MHz以上32-bit Strong ARM-based的信息家电设备上之JavaOS操作系统。透过支持标准的Java执行环境，以Java所开发的应用软件将可直接于SavaJe XE上执行。除了上述两种软件作法外，直接将Java技术做在芯片上，并将之作为信息家电设备的核心，则是另一种解法。目前AJile 公司推出的aJ-100 single chip JVM芯片，可以支持J2ME环境，就是一个典型的范例。 <br />http://www.cooltang.com/box/topic/character/program/cn-java/0505.htm <br />注：ARM的CPU直接支持bytecode。证据见NuclearJava.blogchina.com <br /><br /><br /><br /><br />至于SavaJe的实际市场份额及预测，http://www.giichinese.com/chinese/ar23414_mobile_handsets_toc.html中有，不过要交５５００到７７００美元才能得到。 <br /><br /><br /><br />有关SavaJe的技术信息见： <br />http://java.sun.com/features/2001/06/savaje.html <br />http://sunflash.sun.com/articles/40/3/ja/4013 <br /><br />*************************************** <br />**********第二个纯Java操作系统*********** <br />*************************************** <br />一个开源的JAVA操作系统 <br />jNode: <br />Java New Operating System Design Effort <br /><br />http://jnode.sourceforge.net/portal/ <br />http://sourceforge.net/projects/jnode/ <br />JNode可能是现在开源的Java操作系统中发展最快的了。 <br /><br />至于JNode的性能： <br />http://jnode.sourceforge.net/portal/node/51 <br />可以看到，同样硬件中JNode的性能已经达到了SUN jdk1.4.2的110%，用纯Java写的Java平台的底层的性能超过了C++写的Java平台底层！ <br /><br />至于jdk1.4.2的性能是如何超过C++的，请看NuclearJava.blogchina.com <br /><br /><br />它对jdk1.0已经几乎完全兼容，对于jdk1.5兼容度不到50%。 <br /><br />http://jnode.sourceforge.net/portal/node/174 <br /><br />大家可以下载ISO光盘镜像，用VMware安装试试： <br />http://umn.dl.sourceforge.net/sourceforge/jnode/jnode-x86-0.1.9.iso.gz <br />镜像共有40多M <br /><br />JNode现在在0.1.9版，正在向它的主要release版0.2.0版进发。 <br />一旦JNode发布，就将出现一个非常恐怖的现像： <br />将JNode移植到任何一个不支持bytecode的CPU上只需要改动几Ｋ的汇编代码就行了。 <br />也就是说JNode一旦发布就可以支持几乎所有的硬件体系 <br />http://www.koders.com/info.aspx?c=ProjectInfo&amp;pid=ZK-Ps19mqSFzgjyC*FNiXw__ <br />jNode - <br /><br /><br /><br />*************************************** <br />**********第三个纯Java操作系统*********** <br />*************************************** <br />新一代操作系统JavaOS <br />引言 <br />1997年5月29日,JavaSoft公布了JavaOS&mdash;&mdash;&mdash;为在微处理器上直接运行Java应用程序而设计 <br />的一个高度精简的操作系统。 <br />http://bbs.xmu.edu.cn/bbsgcon?board=Java&amp;file=G.863078295.A&amp;num=4 <br /><br /><br /><br /><br /><br />*************************************** <br />**********第四个纯Java操作系统*********** <br />*************************************** <br />另一个100% 纯Java 操作系统： <br />JXOS： <br />http://sourceforge.net/projects/jxos <br /><br /><br /><br /><br /><br /><br />*************************************** <br />**********第五个纯Java操作系统*********** <br />*************************************** <br />再来看看纯Java操作系统JX的情况： <br />http://www.embyte.com/shop_view.asp?id=23 <br /><br />只有２００Ｋ。 <br /><br />JX可以装到一张软盘中,可以启动电脑，拥有图形界面，用这个启动总比用DOS启动电脑好方便吧？ <br /><br />这是JX启动后的抓屏： <br /><br />http://www.embyte.com/upload/product/a2004112080640.jpg <br /><br /><br />产品简介 <br /><br /><br /><br /><br /><br />JX为一种纯Java操作系统,可以认为是一种概念操作系统.有兴趣参加JX开发的请和我联系: <br />yuanliao@hotmail.com每周五晚上8:00,msn开展jx小组讨论会 <br /><br /><br />详细说明 <br /><br />如果想测试一下目前JX的状况,请用 <br /><br />http://www.embyte.com/upload/product/rawwritewin-0.7.zip <br /><br />工具将 <br /><br />http://www.embyte.com/upload/product/jx-small.floppy <br />操作系统image写入一张软盘,然后启动您的pc <br />您的pc需要如下硬件配置(一般普通PC都能够满足): <br />VESA BIOS 2.0 or greater <br />PS/2 mouse <br />128MB RAM <br /><br /><br /><br /><br /><br /><br /><br />摘要 <br /><br />这篇文章描述了JX操作系统的性能与体系结构。JX是一个用JAVA写的更有利于在其上开发JAVA应用程序的runtime操作系统。我们的工作表明用 <br />JAVA开发一个操作系统是可能的，可以达到好的性能，这得益于面向对象的软件技术和安全类型的编程语言。一个操作系统可以没有MMU硬件的保护也能做到 <br />是安全的。JX基于一个小的微核（负责系统初始化），CPU上下文开关程序，和低级的域保护管理。JAVA代码有组件构成，这些组件被装载到域里，经过验 <br />证，翻译成本地码。域之间是相互隔离的。 <br /><br />JX的体系结构允许多种系统配置，可以是速度较快的monolithic，也可以是非常灵活但是相对较慢的配置。我们通过JX与LINUX的文件系统和 <br />NFS服务，来对比它们的性能。再讨论一下选择不同的系统配置时的性能效果。在monolithic的配置下，JX的文件性能可以达到LINUX的40% <br />到80%，NFS可以达到LINUX的80%。 <br /><br />详细介绍请看下文: <br />http://www.embyte.com/upload/down/JXjj.pdf <br />http://www.embyte.com/upload/down/JXsec.pdf <br /><br /><br /><br /><br /><br /><br /><br />*************************************** <br />**********第六个纯Java操作系统*********** <br />*************************************** <br />JOS <br />http://sourceforge.net/projects/jos <br /><br /><br /><br /><br /><br /><br />*************************************** <br />**********第七个纯Java操作系统*********** <br />*************************************** <br /><br />KaffeOS: A Java Operating System <br /><br />由于不太出名，我就不详细说了，大家自己查相关资料吧 <br />http://www.cs.utah.edu/research/factsheets/kaffeosscrn.pdf <br /><br /><br /><br /><br /><br />*************************************** <br />**********第八个纯Java操作系统*********** <br />*************************************** <br />leJOS： <br /><br />Tiny Java OS for Lego RCX brick. Like its predecessor TinyVM, has tiny Java runtime, under 32K; works as replacement firmware for Lego; Hitachi H8300 processor. To be ported to more small devices. [Open Source, Mozilla] <br />http://lejos.sourceforge.net/ <br /><br /><br /><br /><br />*************************************** <br />**********第九个纯Java操作系统*********** <br />*************************************** <br /><br />SanOS <br /><br />Minimal OS kernel for PC based server appliances. Lets you run java server applications without need to install host OS, only need normal Java HotSpot VM and Sanos. Description, documents, downloads, manifesto, links, contact. [Open Source, BSD] <br />http://www.jbox.dk/sanos/ <br /><br /><br /><br /><br /><br />*************************************** <br />**********第十个纯Java操作系统*********** <br />*************************************** <br />LogOS: <br />Linked object generation Operating System, and other Java on bare metal synthesis technology for embedded systems. Tools to make dynamic, classloadable programs without overhead of traditional OS and JVM software layers. <br />http://www.websprocket.com/ <br /><br /><br /><br /><br /><br /><br /><br />*************************************** <br />*********第十一个纯Java操作系统********** <br />*************************************** <br /><br />关于Java Card 上的java操作系统： <br />http://www.gemplus.com/smart/rd/publications/pdf/Lag02gdc.pdf <br /><br /><br /><br /><br /><br /><br /><br /><br /><br />*************************************** <br />*********第十二个纯Java操作系统********** <br />*************************************** <br />JBed <br /><br />a Java-based Real-Time Operating System <br />详细介绍见： <br />http://www.microjava.com/jvm/software/jit/jbed2?content_id=695 <br />JBed也是１００％纯Java，连驱动程序都是java写的 <br /><br /><br /><br /><br /><br /><br /><br /><br />*************************************** <br />*********第十三个纯Java操作系统********** <br />*************************************** <br /><br />COSC <br /><br />Microkernel-Based Educational Operating System in Java <br />http://www.cosc.brocku.ca/Project/info/javaos.htm <br /><br /><br /><br /><br /><br />*************************************** <br />*********第十四个纯Java操作系统********** <br />*************************************** <br />Janos <br /><br />Java-oriented Active Network Operating System <br />http://www.cs.utah.edu/flux/janos/</span><br /><img src ="http://www.blogjava.net/jackylpz/aggbug/39749.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jackylpz/" target="_blank">过年</a> 2006-04-07 10:32 <a href="http://www.blogjava.net/jackylpz/archive/2006/04/07/39749.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>