﻿<?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-飞鸟JAVA-文章分类-JAVA</title><link>http://www.blogjava.net/yczz/category/10236.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 23 Oct 2007 09:27:53 GMT</lastBuildDate><pubDate>Tue, 23 Oct 2007 09:27:53 GMT</pubDate><ttl>60</ttl><item><title>用jxl读写excel的.xls文件的例子 带样式 </title><link>http://www.blogjava.net/yczz/articles/155232.html</link><dc:creator>飞鸟</dc:creator><author>飞鸟</author><pubDate>Tue, 23 Oct 2007 03:44:00 GMT</pubDate><guid>http://www.blogjava.net/yczz/articles/155232.html</guid><wfw:comment>http://www.blogjava.net/yczz/comments/155232.html</wfw:comment><comments>http://www.blogjava.net/yczz/articles/155232.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yczz/comments/commentRss/155232.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yczz/services/trackbacks/155232.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 有时候我们会需要做excel的报表,下面这个例子详细的给出了读写及定义样式的方法。package&nbsp;com.test;import&nbsp;java.io.File;import&nbsp;java.io.IOException;import&nbsp;jxl.Cell;import&nbsp;jxl.Sheet;import&nbsp;jxl.Wor...&nbsp;&nbsp;<a href='http://www.blogjava.net/yczz/articles/155232.html'>阅读全文</a><img src ="http://www.blogjava.net/yczz/aggbug/155232.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yczz/" target="_blank">飞鸟</a> 2007-10-23 11:44 <a href="http://www.blogjava.net/yczz/articles/155232.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jdom操作xml </title><link>http://www.blogjava.net/yczz/articles/154342.html</link><dc:creator>飞鸟</dc:creator><author>飞鸟</author><pubDate>Fri, 19 Oct 2007 12:34:00 GMT</pubDate><guid>http://www.blogjava.net/yczz/articles/154342.html</guid><wfw:comment>http://www.blogjava.net/yczz/comments/154342.html</wfw:comment><comments>http://www.blogjava.net/yczz/articles/154342.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yczz/comments/commentRss/154342.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yczz/services/trackbacks/154342.html</trackback:ping><description><![CDATA[JDOM是Breet Mclaughlin和Jason Hunter两大Java高手的创作成果，2000年初，JDOM作为一个开放源代码项目正式开始研发。JDOM是一种解析XML的Java工具包。<br />
<br />
JDOM的二进制版本下载：<a href="http://www.jdom.org/downloads/index.html">http://www.jdom.org/downloads/index.html</a><br />
<br />
把解压后的jdom.jar文件加到项目的类路径中，另外便于调试，还要下载它的源代码。<br />
<br />
一、解析XML<br />
要解析的XML文件：<br />
<div style="border-right: rgb(204,204,204) 1px solid; padding-right: 5px; border-top: rgb(204,204,204) 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: rgb(204,204,204) 1px solid; width: 98%; padding-top: 4px; border-bottom: rgb(204,204,204) 1px solid; background-color: rgb(238,238,238)"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: rgb(0,0,0)">&lt;?</span><span style="color: rgb(0,0,0)">xml&nbsp;version</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">1.0</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">&nbsp;encoding</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">gb2312</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">?&gt;</span><span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,0,0)">&lt;</span><span style="color: rgb(0,0,0)">books</span><span style="color: rgb(0,0,0)">&gt;</span><span style="color: rgb(0,0,0)"><br />
&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,0)">&lt;</span><span style="color: rgb(0,0,0)">book&nbsp;email</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">zhoujunhui</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">&gt;</span><span style="color: rgb(0,0,0)"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,0)">&lt;</span><span style="color: rgb(0,0,0)">name</span><span style="color: rgb(0,0,0)">&gt;</span><span style="color: rgb(0,0,0)">rjzjh</span><span style="color: rgb(0,0,0)">&lt;/</span><span style="color: rgb(0,0,0)">name</span><span style="color: rgb(0,0,0)">&gt;</span><span style="color: rgb(0,0,0)"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,0)">&lt;</span><span style="color: rgb(0,0,0)">price</span><span style="color: rgb(0,0,0)">&gt;</span><span style="color: rgb(0,0,0)">60.0</span><span style="color: rgb(0,0,0)">&lt;/</span><span style="color: rgb(0,0,0)">price</span><span style="color: rgb(0,0,0)">&gt;</span><span style="color: rgb(0,0,0)"><br />
&nbsp;&nbsp;</span><span style="color: rgb(0,0,0)">&lt;/</span><span style="color: rgb(0,0,0)">book</span><span style="color: rgb(0,0,0)">&gt;</span><span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,0,0)">&lt;/</span><span style="color: rgb(0,0,0)">books</span><span style="color: rgb(0,0,0)">&gt;</span></div>
<br />
<br />
解析XML的java文件：<br />
<div style="border-right: rgb(204,204,204) 1px solid; padding-right: 5px; border-top: rgb(204,204,204) 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: rgb(204,204,204) 1px solid; width: 98%; padding-top: 4px; border-bottom: rgb(204,204,204) 1px solid; background-color: rgb(238,238,238)"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: rgb(0,128,128)">&nbsp;1</span>&nbsp;<span style="color: rgb(0,0,255)">package</span><span style="color: rgb(0,0,0)">&nbsp;com;<br />
</span><span style="color: rgb(0,128,128)">&nbsp;2</span>&nbsp;<span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">&nbsp;3</span>&nbsp;<span style="color: rgb(0,0,255)">import</span><span style="color: rgb(0,0,0)">&nbsp;java.io.IOException;<br />
</span><span style="color: rgb(0,128,128)">&nbsp;4</span>&nbsp;<span style="color: rgb(0,0,255)">import</span><span style="color: rgb(0,0,0)">&nbsp;java.util.</span><span style="color: rgb(0,0,0)">*</span><span style="color: rgb(0,0,0)">;<br />
</span><span style="color: rgb(0,128,128)">&nbsp;5</span>&nbsp;<span style="color: rgb(0,0,255)">import</span><span style="color: rgb(0,0,0)">&nbsp;org.jdom.</span><span style="color: rgb(0,0,0)">*</span><span style="color: rgb(0,0,0)">;<br />
</span><span style="color: rgb(0,128,128)">&nbsp;6</span>&nbsp;<span style="color: rgb(0,0,255)">import</span><span style="color: rgb(0,0,0)">&nbsp;org.jdom.input.SAXBuilder;&nbsp;<br />
</span><span style="color: rgb(0,128,128)">&nbsp;7</span>&nbsp;<span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">&nbsp;8</span>&nbsp;<span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">class</span><span style="color: rgb(0,0,0)">&nbsp;Test&nbsp;{<br />
</span><span style="color: rgb(0,128,128)">&nbsp;9</span>&nbsp;<span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">10</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,128,0)">/**</span><span style="color: rgb(0,128,0)"><br />
</span><span style="color: rgb(0,128,128)">11</span>&nbsp;<span style="color: rgb(0,128,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span style="color: rgb(128,128,128)">@param</span><span style="color: rgb(0,128,0)">&nbsp;args<br />
</span><span style="color: rgb(0,128,128)">12</span>&nbsp;<span style="color: rgb(0,128,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,128,0)">*/</span><span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">13</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">void</span><span style="color: rgb(0,0,0)">&nbsp;main(String[]&nbsp;args)&nbsp;{<br />
</span><span style="color: rgb(0,128,128)">14</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SAXBuilder&nbsp;sb</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,255)">new</span><span style="color: rgb(0,0,0)">&nbsp;SAXBuilder(</span>false<span style="color: rgb(0,0,0)">);<br />
</span><span style="color: rgb(0,128,128)">15</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Document&nbsp;doc&nbsp;</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">null</span><span style="color: rgb(0,0,0)">;<br />
</span><span style="color: rgb(0,128,128)">16</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">try</span><span style="color: rgb(0,0,0)">&nbsp;{<br />
</span><span style="color: rgb(0,128,128)">17</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;doc&nbsp;</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">&nbsp;sb.build(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">sample.xml</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">);<br />
</span><span style="color: rgb(0,128,128)">18</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: rgb(0,0,255)">catch</span><span style="color: rgb(0,0,0)">&nbsp;(JDOMException&nbsp;e)&nbsp;{<br />
</span><span style="color: rgb(0,128,128)">19</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
</span><span style="color: rgb(0,128,128)">20</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: rgb(0,0,255)">catch</span><span style="color: rgb(0,0,0)">&nbsp;(IOException&nbsp;e)&nbsp;{<br />
</span><span style="color: rgb(0,128,128)">21</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
</span><span style="color: rgb(0,128,128)">22</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br />
</span><span style="color: rgb(0,128,128)">23</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Element&nbsp;root</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">doc.getRootElement();&nbsp;</span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)">获取根元素</span><span style="color: rgb(0,128,0)"><br />
</span><span style="color: rgb(0,128,128)">24</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&nbsp;list</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">root.getChildren(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">book</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">);</span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)">取名字为book的所有元素</span><span style="color: rgb(0,128,0)"><br />
</span><span style="color: rgb(0,128,128)">25</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">for</span><span style="color: rgb(0,0,0)">(</span><span style="color: rgb(0,0,255)">int</span><span style="color: rgb(0,0,0)">&nbsp;i</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">0</span><span style="color: rgb(0,0,0)">;i</span><span style="color: rgb(0,0,0)">&lt;</span><span style="color: rgb(0,0,0)">list.size();i</span><span style="color: rgb(0,0,0)">++</span><span style="color: rgb(0,0,0)">){<br />
</span><span style="color: rgb(0,128,128)">26</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Element&nbsp;element</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">(Element)list.get(i);<br />
</span><span style="color: rgb(0,128,128)">27</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;email</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">element.getAttributeValue(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">email</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">);<br />
</span><span style="color: rgb(0,128,128)">28</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;name</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">element.getChildText(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">name</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">);<br />
</span><span style="color: rgb(0,128,128)">29</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;price</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">element.getChildText(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">price</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">);<br />
</span><span style="color: rgb(0,128,128)">30</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">name:</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">+</span><span style="color: rgb(0,0,0)">name);<br />
</span><span style="color: rgb(0,128,128)">31</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">price:</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">+</span><span style="color: rgb(0,0,0)">price);<br />
</span><span style="color: rgb(0,128,128)">32</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">email:</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">+</span><span style="color: rgb(0,0,0)">email);<br />
</span><span style="color: rgb(0,128,128)">33</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: rgb(0,128,128)">34</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: rgb(0,128,128)">35</span>&nbsp;<span style="color: rgb(0,0,0)">}<br />
</span><span style="color: rgb(0,128,128)">36</span>&nbsp;<span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">37</span>&nbsp;</div>
<br />
解释代码<br />
<span style="font-size: 10pt">引用的类：<br />
<span style="font-size: 12pt">import java.io.FileOutputStream;<br />
import java.io.IOException;<br />
import java.util.Iterator;<br />
import java.util.List;<br />
//下面是引用到JDOM中的类<br />
import org.jdom.Document;<br />
import org.jdom.Element;<br />
import org.jdom.JDOMException;<br />
import org.jdom.input.SAXBuilder;<br />
import org.jdom.output.XMLOutputter;<br />
（1）使用JDOM首先要指定使用什么解析器。如：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SAXBuilder builder=new SAXBuilder(false); 这表示使用的是默认的解析器<br />
（2）得到Document，我们以后要进行的所有操作都是对这个Document操作的：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Document doc=builder.build(xmlpath);<br />
（3）得到根元素：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Element books=doc.getRootElement();<br />
在JDOM中所有的节点（DOM中的概念）都是一个org.jdom.Element类，当然他的子节点也是一个org.jdom.Element类。<br />
（4）得到元素（节点）的集合：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List booklist=books.getChildren("book");<br />
这表示得到&#8220;books&#8221;元素的所在名称为&#8220;book&#8221;的元素，并把这些元素都放到一个List集合中<br />
（5）轮循List集合<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (Iterator iter = booklist.iterator(); iter.hasNext();) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Element book = (Element) iter.next();<br />
&nbsp;&nbsp;&nbsp;&nbsp;｝<br />
还有一种轮循方法是：<br />
&nbsp;&nbsp;&nbsp;&nbsp;for(int i=0;I&lt;booklist.size();I++){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Element book=(Element)booklist.get(i);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
（6）取得元素的属性：<br />
&nbsp;&nbsp;&nbsp;&nbsp;String email=book.getAttributeValue("email");<br />
&nbsp;&nbsp;&nbsp;取得元素book的属性名为&#8220;email&#8221;的属性值。<br />
（7）取得元素的子元素（为最低层元素）的值：<br />
&nbsp;&nbsp;&nbsp;&nbsp;String name=book.getChildTextTrim("name");<br />
&nbsp;&nbsp;&nbsp;&nbsp;注意的是，必须确定book元素的名为&#8220;name&#8221;的子元素只有一个。<br />
（8）改变元素（为最低层元素）的值：<br />
&nbsp;&nbsp;&nbsp;&nbsp;book.getChild("name").setText("alterrjzjh");<br />
&nbsp;&nbsp;&nbsp;&nbsp;这只是对Document的修改，并没有在实际的XML文档中进行修改<br />
（9）保存Document的修改到XML文件中：<br />
&nbsp;&nbsp;&nbsp;XMLOutputter outputter=new XMLOutputter();<br />
&nbsp;&nbsp;&nbsp;&nbsp;outputter.output(doc,new FileOutputStream(xmlpath));<br />
<br />
我们先要有一个XMLOutputter类，再把已经修改了的Document保存进XML文档中。<br />
到此。用JDOM解析和处理XML文档讲解完了，麻雀虽小，五脏俱全。现在已对JDOM有个整体上的概念了吧。<br />
<br />
</span></span>二、生成XML：<br />
java文件：<br />
<div style="border-right: rgb(204,204,204) 1px solid; padding-right: 5px; border-top: rgb(204,204,204) 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: rgb(204,204,204) 1px solid; width: 98%; padding-top: 4px; border-bottom: rgb(204,204,204) 1px solid; background-color: rgb(238,238,238)"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: rgb(0,128,128)">&nbsp;1</span>&nbsp;<span style="color: rgb(0,0,255)">package</span><span style="color: rgb(0,0,0)">&nbsp;com;<br />
</span><span style="color: rgb(0,128,128)">&nbsp;2</span>&nbsp;<span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">&nbsp;3</span>&nbsp;<span style="color: rgb(0,0,255)">import</span><span style="color: rgb(0,0,0)">&nbsp;java.io.FileWriter;<br />
</span><span style="color: rgb(0,128,128)">&nbsp;4</span>&nbsp;<span style="color: rgb(0,0,255)">import</span><span style="color: rgb(0,0,0)">&nbsp;java.io.IOException;<br />
</span><span style="color: rgb(0,128,128)">&nbsp;5</span>&nbsp;<span style="color: rgb(0,0,255)">import</span><span style="color: rgb(0,0,0)">&nbsp;java.util.</span><span style="color: rgb(0,0,0)">*</span><span style="color: rgb(0,0,0)">;<br />
</span><span style="color: rgb(0,128,128)">&nbsp;6</span>&nbsp;<span style="color: rgb(0,0,255)">import</span><span style="color: rgb(0,0,0)">&nbsp;org.jdom.</span><span style="color: rgb(0,0,0)">*</span><span style="color: rgb(0,0,0)">;<br />
</span><span style="color: rgb(0,128,128)">&nbsp;7</span>&nbsp;<span style="color: rgb(0,0,255)">import</span><span style="color: rgb(0,0,0)">&nbsp;org.jdom.input.SAXBuilder;&nbsp;<br />
</span><span style="color: rgb(0,128,128)">&nbsp;8</span>&nbsp;<span style="color: rgb(0,0,255)">import</span><span style="color: rgb(0,0,0)">&nbsp;org.jdom.output.XMLOutputter;<br />
</span><span style="color: rgb(0,128,128)">&nbsp;9</span>&nbsp;<span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">10</span>&nbsp;<span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">class</span><span style="color: rgb(0,0,0)">&nbsp;Test&nbsp;{<br />
</span><span style="color: rgb(0,128,128)">11</span>&nbsp;<span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">12</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,128,0)">/**</span><span style="color: rgb(0,128,0)"><br />
</span><span style="color: rgb(0,128,128)">13</span>&nbsp;<span style="color: rgb(0,128,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span style="color: rgb(128,128,128)">@param</span><span style="color: rgb(0,128,0)">&nbsp;args<br />
</span><span style="color: rgb(0,128,128)">14</span>&nbsp;<span style="color: rgb(0,128,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,128,0)">*/</span><span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">15</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">void</span><span style="color: rgb(0,0,0)">&nbsp;main(String[]&nbsp;args)&nbsp;{<br />
</span><span style="color: rgb(0,128,128)">16</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)">第一步，创建根元素&nbsp;</span><span style="color: rgb(0,128,0)"><br />
</span><span style="color: rgb(0,128,128)">17</span>&nbsp;<span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">18</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Element&nbsp;carElement&nbsp;</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">new</span><span style="color: rgb(0,0,0)">&nbsp;Element(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">car</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">);&nbsp;<br />
</span><span style="color: rgb(0,128,128)">19</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Document&nbsp;myDocument&nbsp;</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">new</span><span style="color: rgb(0,0,0)">&nbsp;Document(carElement);&nbsp;<br />
</span><span style="color: rgb(0,128,128)">20</span>&nbsp;<span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">21</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)">因为一个&nbsp;XML&nbsp;文档必须一直有一个唯一的根元素，所以&nbsp;Document&nbsp;将&nbsp;Element&nbsp;放在它的构造器中。&nbsp;<br />
</span><span style="color: rgb(0,128,128)">22</span>&nbsp;<span style="color: rgb(0,128,0)"><br />
</span><span style="color: rgb(0,128,128)">23</span>&nbsp;<span style="color: rgb(0,128,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)">第二步，添加一个&nbsp;Attribute&nbsp;</span><span style="color: rgb(0,128,0)"><br />
</span><span style="color: rgb(0,128,128)">24</span>&nbsp;<span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">25</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;carElement.setAttribute(</span><span style="color: rgb(0,0,255)">new</span><span style="color: rgb(0,0,0)">&nbsp;Attribute(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">vin</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">,&nbsp;</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">123fhg5869705iop90</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">));&nbsp;<br />
</span><span style="color: rgb(0,128,128)">26</span>&nbsp;<span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">27</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)">第三步，添加其它元素&nbsp;</span><span style="color: rgb(0,128,0)"><br />
</span><span style="color: rgb(0,128,128)">28</span>&nbsp;<span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">29</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;carElement.addContent(</span><span style="color: rgb(0,0,255)">new</span><span style="color: rgb(0,0,0)">&nbsp;Element(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">make</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">).addContent(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">Toyota</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">));&nbsp;<br />
</span><span style="color: rgb(0,128,128)">30</span>&nbsp;<span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">31</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;carElement.addContent(</span><span style="color: rgb(0,0,255)">new</span><span style="color: rgb(0,0,0)">&nbsp;Element(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">model</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">).addContent(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">Celica</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">));&nbsp;<br />
</span><span style="color: rgb(0,128,128)">32</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;carElement.addContent(</span><span style="color: rgb(0,0,255)">new</span><span style="color: rgb(0,0,0)">&nbsp;Element(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">year</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">).addContent(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">1997</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">));&nbsp;<br />
</span><span style="color: rgb(0,128,128)">33</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;carElement.addContent(</span><span style="color: rgb(0,0,255)">new</span><span style="color: rgb(0,0,0)">&nbsp;Element(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">color</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">).addContent(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">green</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">));&nbsp;<br />
</span><span style="color: rgb(0,128,128)">34</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;carElement.addContent(</span><span style="color: rgb(0,0,255)">new</span><span style="color: rgb(0,0,0)">&nbsp;Element(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">license</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">).addContent(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">1ABC234</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">).setAttribute(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">state</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">,&nbsp;</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">CA</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">));&nbsp;<br />
</span><span style="color: rgb(0,128,128)">35</span>&nbsp;<span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">36</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)">第四步，添加一条注释&nbsp;</span><span style="color: rgb(0,128,0)"><br />
</span><span style="color: rgb(0,128,128)">37</span>&nbsp;<span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">38</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;carElement.addContent(</span><span style="color: rgb(0,0,255)">new</span><span style="color: rgb(0,0,0)">&nbsp;Comment(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">Description&nbsp;of&nbsp;a&nbsp;car</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">));&nbsp;<br />
</span><span style="color: rgb(0,128,128)">39</span>&nbsp;<span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">40</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)">第五步，读一个子元素&nbsp;</span><span style="color: rgb(0,128,0)"><br />
</span><span style="color: rgb(0,128,128)">41</span>&nbsp;<span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">42</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Element&nbsp;yearElement&nbsp;</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">&nbsp;carElement.getChild(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">year</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">);&nbsp;<br />
</span><span style="color: rgb(0,128,128)">43</span>&nbsp;<span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">44</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)">第六步，删除子元素&nbsp;</span><span style="color: rgb(0,128,0)"><br />
</span><span style="color: rgb(0,128,128)">45</span>&nbsp;<span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">46</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">boolean</span><span style="color: rgb(0,0,0)">&nbsp;removed&nbsp;</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">&nbsp;carElement.removeChild(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">year</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">);&nbsp;<br />
</span><span style="color: rgb(0,128,128)">47</span>&nbsp;<span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">48</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)">第七步，存盘&nbsp;</span><span style="color: rgb(0,128,0)"><br />
</span><span style="color: rgb(0,128,128)">49</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XMLOutputter&nbsp;outputter&nbsp;</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">new</span><span style="color: rgb(0,0,0)">&nbsp;XMLOutputter();</span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)">用于输出jdom&nbsp;文档</span><span style="color: rgb(0,128,0)"><br />
</span><span style="color: rgb(0,128,128)">50</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FileWriter&nbsp;writer;<br />
</span><span style="color: rgb(0,128,128)">51</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">try</span><span style="color: rgb(0,0,0)">&nbsp;{<br />
</span><span style="color: rgb(0,128,128)">52</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writer&nbsp;</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">new</span><span style="color: rgb(0,0,0)">&nbsp;FileWriter(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">myFile.xml</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">);<br />
</span><span style="color: rgb(0,128,128)">53</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;outputter.output(myDocument,&nbsp;writer);&nbsp;<br />
</span><span style="color: rgb(0,128,128)">54</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writer.close();<br />
</span><span style="color: rgb(0,128,128)">55</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: rgb(0,0,255)">catch</span><span style="color: rgb(0,0,0)">&nbsp;(IOException&nbsp;e)&nbsp;{<br />
</span><span style="color: rgb(0,128,128)">56</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)">&nbsp;TODO&nbsp;自动生成&nbsp;catch&nbsp;块</span><span style="color: rgb(0,128,0)"><br />
</span><span style="color: rgb(0,128,128)">57</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
</span><span style="color: rgb(0,128,128)">58</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br />
</span><span style="color: rgb(0,128,128)">59</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0,128,128)">60</span>&nbsp;<span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">61</span>&nbsp;<span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: rgb(0,128,128)">62</span>&nbsp;<span style="color: rgb(0,0,0)">}<br />
</span><span style="color: rgb(0,128,128)">63</span>&nbsp;<span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">64</span>&nbsp;</div>
<br />
生成的XML: <br />
<div style="border-right: rgb(204,204,204) 1px solid; padding-right: 5px; border-top: rgb(204,204,204) 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: rgb(204,204,204) 1px solid; width: 98%; padding-top: 4px; border-bottom: rgb(204,204,204) 1px solid; background-color: rgb(238,238,238)"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: rgb(0,0,0)">&lt;?</span><span style="color: rgb(0,0,0)">xml&nbsp;version</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">1.0</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">&nbsp;encoding</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">UTF-8</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">?&gt;</span><span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,0,0)">&lt;</span><span style="color: rgb(0,0,0)">car&nbsp;vin</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">123fhg5869705iop90</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">&gt;</span><span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,0,0)">&lt;</span><span style="color: rgb(0,0,0)">make</span><span style="color: rgb(0,0,0)">&gt;</span><span style="color: rgb(0,0,0)">Toyota</span><span style="color: rgb(0,0,0)">&lt;/</span><span style="color: rgb(0,0,0)">make</span><span style="color: rgb(0,0,0)">&gt;</span><span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,0,0)">&lt;</span><span style="color: rgb(0,0,0)">model</span><span style="color: rgb(0,0,0)">&gt;</span><span style="color: rgb(0,0,0)">Celica</span><span style="color: rgb(0,0,0)">&lt;/</span><span style="color: rgb(0,0,0)">model</span><span style="color: rgb(0,0,0)">&gt;</span><span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,0,0)">&lt;</span><span style="color: rgb(0,0,0)">color</span><span style="color: rgb(0,0,0)">&gt;</span><span style="color: rgb(0,0,0)">green</span><span style="color: rgb(0,0,0)">&lt;/</span><span style="color: rgb(0,0,0)">color</span><span style="color: rgb(0,0,0)">&gt;</span><span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,0,0)">&lt;</span><span style="color: rgb(0,0,0)">license&nbsp;state</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">CA</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">&gt;</span><span style="color: rgb(0,0,0)">1ABC234</span><span style="color: rgb(0,0,0)">&lt;/</span><span style="color: rgb(0,0,0)">license</span><span style="color: rgb(0,0,0)">&gt;</span><span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,0,0)">&lt;!--</span><span style="color: rgb(0,0,0)">Description&nbsp;of&nbsp;a&nbsp;car</span><span style="color: rgb(0,0,0)">--&gt;</span><span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,0,0)">&lt;/</span><span style="color: rgb(0,0,0)">car</span><span style="color: rgb(0,0,0)">&gt;</span></div>
<img src ="http://www.blogjava.net/yczz/aggbug/154342.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yczz/" target="_blank">飞鸟</a> 2007-10-19 20:34 <a href="http://www.blogjava.net/yczz/articles/154342.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java生成Excel文件通用程序</title><link>http://www.blogjava.net/yczz/articles/154334.html</link><dc:creator>飞鸟</dc:creator><author>飞鸟</author><pubDate>Fri, 19 Oct 2007 11:43:00 GMT</pubDate><guid>http://www.blogjava.net/yczz/articles/154334.html</guid><wfw:comment>http://www.blogjava.net/yczz/comments/154334.html</wfw:comment><comments>http://www.blogjava.net/yczz/articles/154334.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yczz/comments/commentRss/154334.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yczz/services/trackbacks/154334.html</trackback:ping><description><![CDATA[我们用到了JXL的一些知识，关于JXL我懂得也不是很多，但是找到了一篇很不错的文章，我想也该推荐大家去看看。好东西，自然是大家分享。
<p><a href="http://blog.csdn.net/airskys/archive/2005/03/31/334548.aspx">http://blog.csdn.net/airskys/archive/2005/03/31/334548.aspx</a></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 接下来看看我们的通用程序是怎么写的。其实也没有什么敲门，只是传进去了一个将要从数据库中读出数据的SQL语句，将执行出来的结果写入到&nbsp;Excel中显示出来而已。</p>
<p>&nbsp;</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 95%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;jxl.Workbook;<br />
</span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;jxl.write.Label;<br />
</span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;jxl.write.WritableWorkbook;<br />
</span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;jxl.write.WriteException;<br />
<br />
<br />
</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;getExcelResult(String&nbsp;sql,OutputStream&nbsp;os)&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;SQLException,IOException,&nbsp;WriteException{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">首先获取结果集<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">这里获取RowSet的方法可以自己写</span><span style="color: #008000"><br />
</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CachedRowSet&nbsp;crs&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.GetResult(sql);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">然后将结果集转化为Excel输出<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">初始化工作</span><span style="color: #008000"><br />
</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WritableWorkbook&nbsp;wwb&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">try</span><span style="color: #000000">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wwb&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;Workbook.createWorkbook(os);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">创建工作表</span><span style="color: #008000"><br />
</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jxl.write.WritableSheet&nbsp;ws&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;wwb.createSheet(</span><span style="color: #000000">"</span><span style="color: #000000">Sheet1</span><span style="color: #000000">"</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">逐行添加数据</span><span style="color: #008000"><br />
</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;i&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">&nbsp;(crs.next()){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;j</span><span style="color: #000000">=</span><span style="color: #000000">1</span><span style="color: #000000">;j</span><span style="color: #000000">&lt;=</span><span style="color: #000000">crs.getMetaData().getColumnCount();j</span><span style="color: #000000">++</span><span style="color: #000000">){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;s&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;crs.getString(j);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Label&nbsp;labelC&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Label(j</span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000">,&nbsp;i,&nbsp;s);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ws.addCell(labelC);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i</span><span style="color: #000000">++</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff">catch</span><span style="color: #000000">&nbsp;(Exception&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.error(</span><span style="color: #000000">"</span><span style="color: #000000">export&nbsp;excel&nbsp;error:</span><span style="color: #000000">"</span><span style="color: #000000">+</span><span style="color: #000000">e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff">finally</span><span style="color: #000000">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(wwb&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wwb.write();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wwb.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
</div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 看到了吧！其实这个方法很简单，就是提供一个查询的SQL语句和一个OutPutStream对象就可以了。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 接下来看看我是怎么在JSP页面中调用并且生成文档，然后提示用户是打开还是保存的。</p>
<p>&nbsp;</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 95%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><span style="color: #000000">&lt;</span><span style="color: #000000">body</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;%</span><span style="color: #000000"><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response.reset();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response.setContentType(</span><span style="color: #000000">"</span><span style="color: #000000">application/vnd.ms-excel</span><span style="color: #000000">"</span><span style="color: #000000">);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;sql</span><span style="color: #000000">=</span><span style="color: #000000">request.getParameter(</span><span style="color: #000000">"</span><span style="color: #000000">sql</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sqlconn.getExcelResult(sql,response.getOutputStream());<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">%&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #000000">&lt;/</span><span style="color: #000000">body</span><span style="color: #000000">&gt;</span></div>
</div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在前一个页面中提交要查询的SQL语句，在这里得到后，调用getExcelResult()方法创建Excel文件，就在这里一步完成了。可以看到，这里的OutPutStream对象我使用了Response的getOutPutSteam()方法得到了一个OutPutSteam，执行的结果将会对response进行操作。在此之前，已经设定JSP文件的ContentType为<span style="color: #000000">application/vnd.ms-excel，即会得到这个response对象操作形成的excel文件。</span></p>
<p><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当然，这样执行出来的结果不是很好看。所以，可以想办法修改生成文档的样式等。关于这方面，上面的地址中有很详细的介绍。非常使用。大家可以根据自己的情况写出各种各样的样式来，真是不错啊。</span></p>
<img src ="http://www.blogjava.net/yczz/aggbug/154334.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yczz/" target="_blank">飞鸟</a> 2007-10-19 19:43 <a href="http://www.blogjava.net/yczz/articles/154334.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JXL入门</title><link>http://www.blogjava.net/yczz/articles/154333.html</link><dc:creator>飞鸟</dc:creator><author>飞鸟</author><pubDate>Fri, 19 Oct 2007 11:42:00 GMT</pubDate><guid>http://www.blogjava.net/yczz/articles/154333.html</guid><wfw:comment>http://www.blogjava.net/yczz/comments/154333.html</wfw:comment><comments>http://www.blogjava.net/yczz/articles/154333.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yczz/comments/commentRss/154333.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yczz/services/trackbacks/154333.html</trackback:ping><description><![CDATA[<p>要往xls文件里面写入数据的时候需要注意的是第一要新建一个xls文件 <br />
<span class="Code">OutputStream os=new FileOutputStream("c:\\excel2.xls"); </span></p>
<p>再建完这个文件的时候再建立工作文件 <br />
jxl.write.WritableWorkbook wwb = Workbook.createWorkbook(new File(os)); </p>
<p>如果这个文件已经存在,那么我们可以在这个文件里面加入一个sheet为了和以前的数据进行分开; <br />
jxl.write.WritableSheet ws = wwb.createSheet("Test Sheet 1", 0); <br />
在createSheet方法里前面的参数是sheet名，后面是要操作的sheet号 </p>
<p>接下来就可以往这个文件里面写入数据了 </p>
<p><br />
写入数据的时候注意的格式 </p>
<p><br />
（1）添加的字体样式 <br />
jxl.write.WritableFont wf = new jxl.write.WritableFont(WritableFont.TIMES, 18, WritableFont.BOLD, true); <br />
WritableFont()方法里参数说明： <br />
这个方法算是一个容器，可以放进去好多属性 <br />
第一个:字体 ,WritableFont.TIMES<br />
第二个:大小,18 <br />
第三个: 是否为粗体,WritableFont.BOLD&nbsp;或WritableFont.NO_BOLD&nbsp;<br />
第四个: 判断是否为斜体,选择true时为斜体 <br />
第五个: 样式,UnderlineStyle.NO_UNDERLINE 下划线 <br />
第六个: 颜色,jxl.format.Colour.RED 字体颜色是红色的 </p>
<p>jxl.write.WritableCellFormat wcfF = new jxl.write.WritableCellFormat(wf); </p>
<p>jxl.write.Label labelC = new jxl.write.Label(0, 0, "This is a Label cell"，wcfF); <br />
ws.addCell(labelC); <br />
在Label()方法里面有三个参数 <br />
第一个是代表列数, <br />
第二是代表行数， <br />
第三个代表要写入的内容 <br />
第四个是可选项，是输入这个label里面的样式 <br />
然后通过写sheet的方法addCell（）把内容写进sheet里面。 </p>
<p>（2）添加带有formatting的Number对象 <br />
jxl.write.NumberFormat nf = new jxl.write.NumberFormat("#.##"); </p>
<p><br />
（3）添加Number对象 <br />
（3.1）显示number对象数据的格式 </p>
<p>jxl.write.NumberFormat nf = new jxl.write.NumberFormat("#.##"); <br />
jxl.write.WritableCellFormat wcfN = new jxl.write.WritableCellFormat(nf); </p>
<p>jxl.write.Number labelNF = new jxl.write.Number(1, 1, 3.1415926, wcfN); <br />
ws.addCell(labelNF); <br />
Number()方法参数说明: <br />
前两上表示输入的位置 <br />
第三个表示输入的内容 </p>
<p><br />
（4）添加Boolean对象 <br />
jxl.write.Boolean labelB = new jxl.write.Boolean(0, 2, false); <br />
ws.addCell(labelB); </p>
<p><br />
（5）添加DateTime对象 <br />
jxl.write.DateTime labelDT = new jxl.write.DateTime(0, 3, new java.util.Date()); <br />
ws.addCell(labelDT); <br />
DateTime()方法的参数说明 <br />
前两个表示输入的位置 <br />
第三个表示输入的当前时间 </p>
<p><br />
（6）添加带有formatting的DateFormat对象 <br />
这个显示当前时间的所有信息，包括年月日小时分秒 <br />
jxl.write.DateFormat df = new jxl.write.DateFormat("dd MM yyyy hh:mm:ss"); <br />
jxl.write.WritableCellFormat wcfDF = new jxl.write.WritableCellFormat(df); <br />
jxl.write.DateTime labelDTF = new jxl.write.DateTime(1, 3, new java.util.Date(), wcfDF); <br />
ws.addCell(labelDTF); </p>
<p>（7）添加带有字体颜色Formatting的对象 <br />
<span class="Code">
<p>jxl.write.WritableFont wfc = new jxl.write.WritableFont(WritableFont.ARIAL, 10, WritableFont.NO_BOLD, false,UnderlineStyle.NO_UNDERLINE, jxl.format.Colour.RED); <br />
jxl.write.WritableCellFormat wcfFC = new jxl.write.WritableCellFormat(wfc); </p>
<p>import="jxl.format.* <br />
jxl.write.WritableFont wfc = new jxl.write.WritableFont(WritableFont.ARIAL,20,WritableFont.BOLD,false,UnderlineStyle.NO_UNDERLINE,jxl.format.Colour.GREEN); </p>
<p>（8）设置单元格样式 </p>
</span>
<p>&nbsp;</p>
<p>jxl.write.WritableFont wfc = new jxl.write.WritableFont(WritableFont.ARIAL, 10, WritableFont.NO_BOLD, false,UnderlineStyle.NO_UNDERLINE, jxl.format.Colour.RED); <br />
jxl.write.WritableCellFormat wcfFC = new jxl.write.WritableCellFormat(wfc); </p>
<p>import="jxl.format.* <br />
jxl.write.WritableFont wfc = new jxl.write.WritableFont(WritableFont.ARIAL,20,WritableFont.BOLD,false,UnderlineStyle.NO_UNDERLINE,jxl.format.Colour.GREEN); </p>
<p>（8）设置单元格样式 </p>
<p>jxl.write.WritableCellFormat wcfFC = new jxl.write.WritableCellFormat(wfc); <br />
wcfFC.setBackGround(jxl.format.Colour.RED);//设置单元格的颜色为红色 <br />
wcfFC = new jxl.write.Label(6,0,"i love china",wcfFC);</p>
<img src ="http://www.blogjava.net/yczz/aggbug/154333.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yczz/" target="_blank">飞鸟</a> 2007-10-19 19:42 <a href="http://www.blogjava.net/yczz/articles/154333.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>eclipse最实用的手记</title><link>http://www.blogjava.net/yczz/articles/136323.html</link><dc:creator>飞鸟</dc:creator><author>飞鸟</author><pubDate>Mon, 13 Aug 2007 03:12:00 GMT</pubDate><guid>http://www.blogjava.net/yczz/articles/136323.html</guid><wfw:comment>http://www.blogjava.net/yczz/comments/136323.html</wfw:comment><comments>http://www.blogjava.net/yczz/articles/136323.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yczz/comments/commentRss/136323.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yczz/services/trackbacks/136323.html</trackback:ping><description><![CDATA[<div class=cnt>
<div class=quote>熱鍵篇：<br>Template：Alt + /<br>修改處：視窗-&gt;喜好設定-&gt;工作台-&gt;按鍵-&gt;編輯-&gt;內容輔助。<br>個人習慣：Shift+SPACE(空白)。<br>簡易說明：編輯程式碼時，打sysout +Template啟動鍵，就<br>會自動出現：System.out.println(); 。<br>設定Template的格式：視窗-&gt;喜好設定-&gt;Java-&gt;編輯器-&gt;範本。<br><br>程式碼自動排版：Ctrl+Shift+F<br>修改處：視窗-&gt;喜好設定-&gt;工作台-&gt;按鍵-&gt;程式碼-&gt;格式。<br>個人習慣：Alt+Z。<br>自動排版設定：視窗-&gt;喜好設定-&gt;Java-&gt;程式碼格式製作程式。<br>樣式頁面-&gt;將插入tab(而非空白鍵)以內縮，該選項取消勾選<br>，下面空格數目填4，這樣在自動編排時會以空格4作縮排。<br><br>快速執行程式：Ctrl + F11<br>個人習慣：ALT+X<br>修改處：視窗-&gt;喜好設定-&gt;工作台-&gt;按鍵-&gt;執行-&gt;啟動前一次的啟動作業。<br>簡易說明：第一次執行時，它會詢問您執行模式，<br>設置好後，以後只要按這個熱鍵，它就會快速執行。<br>..我覺得很順手^__^<br><br>自動匯入所需要的類別：Ctrl+Shift+O<br>簡易說明：<br>假設我們沒有Import任何類別時，當我們在程式裡打入：<br>BufferedReader buf =new BufferedReader(new InputStreamReader(System.in));<br>此時Eclipse會警示說沒有匯入類別，這時我們只要按下Ctrl+Shift+O<br>，它就會自動幫我們Import類別。<br><br>查看使用類別的原始碼：Ctrl+滑鼠左鍵點擊<br>簡易說明：可以看到您所使用類別的原始碼。<br><br>將選取的文字註解起來：Ctrl+/<br>簡易說明：Debug時很方便。<br>修改處：視窗-&gt;喜好設定-&gt;工作台-&gt;按鍵-&gt;程式碼-&gt;註解<br><br>視景切換：Ctrl+F8<br>個人習慣：Alt+S。<br>修改處：視窗-&gt;喜好設定-&gt;工作台-&gt;按鍵-&gt;視窗-&gt;下一個視景。<br>簡易說明：可以方便我們快速切換編輯、除錯等視景。<br><br>遍歷各編輯器: Ctrl+F6 <br>簡易說明：可以方便我們快速切換編輯器，Ctrl+F6 彈齣當前所選編輯器的列錶<br><br><br>密技篇：<br>一套Eclipse可同時切換，英文、繁體、簡體顯示：<br>1.首先要先安裝完中文化包。<br>2.在桌面的捷徑後面加上參數即可，<br>英文-&gt; -nl "zh_US"<br>繁體-&gt; -nl "zh_TW"<br>簡體-&gt; -nl "zh_CN"。<br>(其它語系以此類推)<br>像我2.1.2中文化後，我在我桌面的Eclipse捷徑加入參數-n1 "zh_US"。<br>"C:Program Fileseclipseeclipse.exe" -n "zh_US"<br>介面就會變回英文語系嚕。<br><br>利用Eclipse，在Word編輯文書時可不必將程式碼重新編排：<br>將Eclipse程式編輯區的程式碼整個複製下來(Ctrl+C)，直接貼(Ctrl+V)到<br>Word或WordPad上，您將會發現在Word裡的程式碼格式，跟Eclipse<br>所設定的完全一樣，包括字型、縮排、關鍵字顏色。我曾試過JBuilder<br>、GEL、NetBeans...使用複製貼上時，只有縮排格式一樣，字型、顏<br>色等都不會改變。<br><br>外掛篇：<br>外掛安裝：將外掛包下載回來後，將其解壓縮後，您會發現features、<br>plugins這2個資料夾，將裡面的東西都複製或移動到Eclipse的features<br>、plugins資料夾內後，重新啟動Eclipse即可。<br><br>讓Eclipse可以像JBuilderX一樣使用拖拉方式建構GUI的外掛：<br>1.Jigloo SWT/Swing GUI Builder ：<br><a href="http://cloudgarden.com/jigloo/index.html" target=_blank><u><font color=#0000ff>http://cloudgarden.com/jigloo/index.html</font></u></a><br>下載此版本：Jigloo plugin for Eclipse (using Java 1.4 or 1.5)<br>安裝後即可由檔案-&gt;新建-&gt;其它-&gt;GUI Form選取要建構的GUI類型。<br><br>2.Eclipse Visual Editor Project：<br><a href="http://www.eclipse.org/vep/" target=_blank><u><font color=#0000ff>http://www.eclipse.org/vep/</font></u></a><br>點選下方Download Page，再點選Latest Release 0.5.0進入下載。<br>除了VE-runtime-0.5.0.zip要下載外，以下這2個也要：<br>EMF build 1.1.1: (build page) (download zip) <br>GEF Build 2.1.2: (build page) (download zip) <br><br>3.0 M8版本，請下載：<br>EMF build I200403250631<br>GEF Build I20040330<br>VE-runtime-1.0M1<br><br>安裝成功後，便可由File-&gt;New-&gt;Visual Class開始UI設計。<br>安裝成功後，即可由新建-&gt;Java-&gt;AWT與Swing裡選擇<br>所要建構的GUI類型開始進行設計。VE必須配合著對應<br>版本，才能正常使用，否則即使安裝成功，使用上仍會<br>有問題。<br><br>使用Eclipse來開發JSP程式：<br>外掛名稱：lomboz(下載頁面)<br><a href="http://forge.objectweb.org/project/showfiles.php?group_id=97" target=_blank><u><font color=#0000ff>http://forge.objectweb.org/project/showfiles.php?group_id=97</font></u></a><br>請選擇適合自己版本的lomboz下載，lomboz.212.p1.zip表示2.1.2版，<br>lomboz.3m7.zip表示M7版本....以此類推。<br>lomboz安裝以及設置教學：<br>Eclipse開發JSP-教學文件<br><br>Java轉exe篇：<br>實現方式：Eclipse搭配JSmooth(免費)。<br>1.先由Eclipse製作包含Manifest的JAR。<br>製作教學<br>2.使用JSmooth將做好的JAR包裝成EXE。<br>JSmooth下載頁面：<br><a href="http://jsmooth.sourceforge.net/index.php" target=_blank><u><font color=#0000ff>http://jsmooth.sourceforge.net/index.php</font></u></a><br>3.製作完成的exe檔，可在有裝置JRE的Windows上執行。<br><br>Eclipse-Java編輯器最佳設定：<br>編輯器字型設定：工作台-&gt;字型-&gt;Java編輯器文字字型。<br>(建議設定Courier New -regular 10)<br><br>編輯器相關設定：視窗-&gt;喜好設定-&gt;Java-&gt;編輯器<br><br>外觀：顯示行號、強調對稱顯示的方括號、強調顯示現行行、<br>顯示列印邊距，將其勾選，Tab寬度設4，列印編距欄位設80。<br>程式碼協助：採預設即可。<br>語法：可設定關鍵字、字串等等的顯示顏色。<br>附註：採預設即可。<br>輸入：全部欄位都勾選。<br>浮動說明：採預設即可。<br>導覽：採預設即可。<br><br>使自動排版排出來的效果，最符合Java設計慣例的設定：<br>自動排版設定：視窗-&gt;喜好設定-&gt;Java-&gt;程式碼製作格式。<br><br>換行：全部不勾選。<br>分行：行長度上限設：80。<br>樣式：只將強制轉型後插入空白勾選。<br>內縮空格數目：設為4。<br><br>Eclipse的教學文件：<br>Eclipse 3.0系列熱鍵表 - 中英對照解說版 (by sungo) <br>Window+GCC+CDT用Eclipse開發C、C++ (by sungo) <br><br>其它：<br>擴充Eclipse的Java 開發工具(中文)<br>使用Eclipse開發J2EE 應用程式(中文)<br>使用Eclipse平台進行除錯(中文)<br>用Eclipse進行XML 開發(中文)<br>開發Eclipse外掛程式(中文)<br>國際化您的Eclipse外掛程式(英文)<br>將Swing編輯器加入Eclipse(英文)<br>如何測試你的Eclipse plug-in符合國際市場需求(英文)<br><br>Eclipse的相關網站：<br><a href="http://eclipse-plugins.2y.net/eclipse/index.jsp" target=_blank><font color=#0000ff><u>http://eclipse-plugins.2y.net/eclipse/index.jsp</u></font></a><br><a href="http://www.eclipseplugincentral.com/" target=_blank><u><font color=#0000ff>http://www.eclipseplugincentral.com/</font></u></a><br>Eclipse相關教學[簡體]<br><br>BufferedReader buf =new BufferedReader(new InputStreamReader(System.in));<br>此時Eclipse會警示說沒有匯入類別，這時我們只要按下Ctrl+Shift+O<br>，它就會自動幫我們Import類別。<br><br>查看使用類別的原始碼：Ctrl+滑鼠左鍵點擊<br>簡易說明：可以看到您所使用類別的原始碼。<br><br>將選取的文字註解起來：Ctrl+/<br>簡易說明：Debug時很方便。<br>修改處：視窗-&gt;喜好設定-&gt;工作台-&gt;按鍵-&gt;程式碼-&gt;註解<br><br>視景切換：Ctrl+F8<br>個人習慣：Alt+S。<br>修改處：視窗-&gt;喜好設定-&gt;工作台-&gt;按鍵-&gt;視窗-&gt;下一個視景。<br>簡易說明：可以方便我們快速切換編輯、除錯等視景。<br><br>遍歷各編輯器: Ctrl+F6 <br>簡易說明：可以方便我們快速切換編輯器，Ctrl+F6 彈齣當前所選編輯器的列錶<br><br><br>密技篇：<br>一套Eclipse可同時切換，英文、繁體、簡體顯示：<br>1.首先要先安裝完中文化包。<br>2.在桌面的捷徑後面加上參數即可，<br>英文-&gt; -nl "zh_US"<br>繁體-&gt; -nl "zh_TW"<br>簡體-&gt; -nl "zh_CN"。<br>(其它語系以此類推)<br>像我2.1.2中文化後，我在我桌面的Eclipse捷徑加入參數-n1 "zh_US"。<br>"C:Program Fileseclipseeclipse.exe" -n "zh_US"<br>介面就會變回英文語系嚕。<br><br>利用Eclipse，在Word編輯文書時可不必將程式碼重新編排：<br>將Eclipse程式編輯區的程式碼整個複製下來(Ctrl+C)，直接貼(Ctrl+V)到<br>Word或WordPad上，您將會發現在Word裡的程式碼格式，跟Eclipse<br>所設定的完全一樣，包括字型、縮排、關鍵字顏色。我曾試過JBuilder<br>、GEL、NetBeans...使用複製貼上時，只有縮排格式一樣，字型、顏<br>色等都不會改變。<br><br>外掛篇：<br>外掛安裝：將外掛包下載回來後，將其解壓縮後，您會發現features、<br>plugins這2個資料夾，將裡面的東西都複製或移動到Eclipse的features<br>、plugins資料夾內後，重新啟動Eclipse即可。<br><br>讓Eclipse可以像JBuilderX一樣使用拖拉方式建構GUI的外掛：<br>1.Jigloo SWT/Swing GUI Builder ：<br><a href="http://cloudgarden.com/jigloo/index.html" target=_blank><u><font color=#0000ff>http://cloudgarden.com/jigloo/index.html</font></u></a><br>下載此版本：Jigloo plugin for Eclipse (using Java 1.4 or 1.5)<br>安裝後即可由檔案-&gt;新建-&gt;其它-&gt;GUI Form選取要建構的GUI類型。<br><br>2.Eclipse Visual Editor Project：<br><a href="http://www.eclipse.org/vep/" target=_blank><u><font color=#0000ff>http://www.eclipse.org/vep/</font></u></a><br>點選下方Download Page，再點選Latest Release 0.5.0進入下載。<br>除了VE-runtime-0.5.0.zip要下載外，以下這2個也要：<br>EMF build 1.1.1: (build page) (download zip) <br>GEF Build 2.1.2: (build page) (download zip) <br><br>3.0 M8版本，請下載：<br>EMF build I200403250631<br>GEF Build I20040330<br>VE-runtime-1.0M1<br><br>安裝成功後，便可由File-&gt;New-&gt;Visual Class開始UI設計。<br>安裝成功後，即可由新建-&gt;Java-&gt;AWT與Swing裡選擇<br>所要建構的GUI類型開始進行設計。VE必須配合著對應<br>版本，才能正常使用，否則即使安裝成功，使用上仍會<br>有問題。<br><br>使用Eclipse來開發JSP程式：<br>外掛名稱：lomboz(下載頁面)<br><a href="http://forge.objectweb.org/project/showfiles.php?group_id=97" target=_blank><u><font color=#0000ff>http://forge.objectweb.org/project/showfiles.php?group_id=97</font></u></a><br>請選擇適合自己版本的lomboz下載，lomboz.212.p1.zip表示2.1.2版，<br>lomboz.3m7.zip表示M7版本....以此類推。<br>lomboz安裝以及設置教學：<br>Eclipse開發JSP-教學文件<br><br>Java轉exe篇：<br>實現方式：Eclipse搭配JSmooth(免費)。<br>1.先由Eclipse製作包含Manifest的JAR。<br>製作教學<br>2.使用JSmooth將做好的JAR包裝成EXE。<br>JSmooth下載頁面：<br><a href="http://jsmooth.sourceforge.net/index.php" target=_blank><u><font color=#0000ff>http://jsmooth.sourceforge.net/index.php</font></u></a><br>3.製作完成的exe檔，可在有裝置JRE的Windows上執行。<br><br>Eclipse-Java編輯器最佳設定：<br>編輯器字型設定：工作台-&gt;字型-&gt;Java編輯器文字字型。<br>(建議設定Courier New -regular 10)<br><br>編輯器相關設定：視窗-&gt;喜好設定-&gt;Java-&gt;編輯器<br><br>外觀：顯示行號、強調對稱顯示的方括號、強調顯示現行行、<br>顯示列印邊距，將其勾選，Tab寬度設4，列印編距欄位設80。<br>程式碼協助：採預設即可。<br>語法：可設定關鍵字、字串等等的顯示顏色。<br>附註：採預設即可。<br>輸入：全部欄位都勾選。<br>浮動說明：採預設即可。<br>導覽：採預設即可。<br><br>使自動排版排出來的效果，最符合Java設計慣例的設定：<br>自動排版設定：視窗-&gt;喜好設定-&gt;Java-&gt;程式碼製作格式。<br><br>換行：全部不勾選。<br>分行：行長度上限設：80。<br>樣式：只將強制轉型後插入空白勾選。<br>內縮空格數目：設為4。<br><br>Eclipse的教學文件：<br>Eclipse 3.0系列熱鍵表 - 中英對照解說版 (by sungo) <br>Window+GCC+CDT用Eclipse開發C、C++ (by sungo) <br><br>其它：<br>擴充Eclipse的Java 開發工具(中文)<br>使用Eclipse開發J2EE 應用程式(中文)<br>使用Eclipse平台進行除錯(中文)<br>用Eclipse進行XML 開發(中文)<br>開發Eclipse外掛程式(中文)<br>國際化您的Eclipse外掛程式(英文)<br>將Swing編輯器加入Eclipse(英文)<br>如何測試你的Eclipse plug-in符合國際市場需求(英文)<br><br>Eclipse的相關網站：<br><a href="http://eclipse-plugins.2y.net/eclipse/index.jsp" target=_blank><font color=#0000ff><u>http://eclipse-plugins.2y.net/eclipse/index.jsp</u></font></a><br><a href="http://www.eclipseplugincentral.com/" target=_blank><u><font color=#0000ff>http://www.eclipseplugincentral.com/</font></u></a><br>Eclipse相關教學[簡體]<br><br>最新eclipse下载,eclipse 下载中文,eclipse 入门,eclipse 源代码,eclipse servlet,eclipse<br>ant,eclipse 常用,eclipse gui,hibernate eclipse,eclipse 调试,eclipse docs,eclipse<br>junit ibm,eclipse lomboz,eclipse 使用方法,eclipse 3.0 教程,eclipse 外挂插件，教程等</div>
</div>
<img src ="http://www.blogjava.net/yczz/aggbug/136323.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yczz/" target="_blank">飞鸟</a> 2007-08-13 11:12 <a href="http://www.blogjava.net/yczz/articles/136323.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>正则表达式30分钟入门教程</title><link>http://www.blogjava.net/yczz/articles/135351.html</link><dc:creator>飞鸟</dc:creator><author>飞鸟</author><pubDate>Wed, 08 Aug 2007 13:16:00 GMT</pubDate><guid>http://www.blogjava.net/yczz/articles/135351.html</guid><wfw:comment>http://www.blogjava.net/yczz/comments/135351.html</wfw:comment><comments>http://www.blogjava.net/yczz/articles/135351.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yczz/comments/commentRss/135351.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yczz/services/trackbacks/135351.html</trackback:ping><description><![CDATA[<h1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;正则表达式30分钟入门教程</h1>
<p id=meta>本文目标</p>
<p>30分钟内让你明白正则表达式是什么，并对它有一些基本的了解，让你可以在自己的程序或网页里使用它。</p>
<h2 id=howtouse>如何使用本教程</h2>
<p class=important>最重要的是——请给我<strong>30分钟</strong>，如果你没有使用正则表达式的经验，请不要试图在30<strong>秒</strong>内入门。当然，如果你是超人，那自然得另当别论。</p>
<p>别被下面那些复杂的表达式吓倒，只要跟着我一步一步来，你会发现正则表达式其实并<span lang=zh-cn>没有</span>你想像中的那么困难。当然，如果你看完了这篇教程之后，发现自己明白了很多，却又几乎什么都记不得，那也是很正常的——我认为，没接触过正则表达式的人在看完这篇教程后，能把提到过的语法记住80%以上的可能性为零。这里只是让你明白基本的原理，以后你还需要多练习，多使用，才能熟练掌握正则表达式。</p>
<p>除了作为入门教程之外，本文还试图成为可以在日常工作中使用的正则表达式语法参考手册。就作者本人的经历来说，这个目标还是完成得不错的——你看，我自己也没能把所有的东西记下来，不是吗？</p>
<p>文本格式约定：<span class=name><strong>专业术语</strong></span>&nbsp;<span class=code><font color=#0000ff>元字符/语法格式</font></span>&nbsp;<span class=regex><font color=#ff0000>正则表达式</font></span>&nbsp;<span class=part><font color=#008000>正则表达式中的一部分(用于分析)</font></span>&nbsp;<span class=string><em>用于在其中搜索的字符串</em></span>&nbsp;<span class=desc><u>对正则表达式或其中一部分的说明</u></span><a id=clearButton accessKey=c onclick="return clearFormats();" href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm"><font style="BACKGROUND-COLOR: #eeeeee" color=#800080>清除格式</font></a></p>
<h2 id=introduction>正则表达式到底是什么？</h2>
<p>在编写处理字符串的程序或网页时，经常会有查找符合某些复杂规则的字符串的需要。<span class=name><strong>正则表达式</strong></span>就是用于描述这些规则的工具。换句话说，正则表达式就是记录文本规则的代码。</p>
<p>很可能你使用过Windows/Dos下用于文件查找的<span class=name><strong>通配符(wildcard)</strong></span>，也就是<span class=code><font color=#0000ff>*</font></span>和<span class=code><font color=#0000ff>?</font></span>。如果你想查找某个目录下的所有的Word文档的话，你会搜索<span style="COLOR: red">*.doc</span>。在这里，<span class=code><font color=#0000ff>*</font></span>会被解释成任意的<a title=参考 href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#reference"><u><font color=#800080>字符串</font></u></a>。和通配符类似，正则表达式也是用来进行<a title=参考 href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#reference"><u><font color=#800080>文本</font></u></a><a title=参考 href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#reference"><u><font color=#800080>匹配</font></u></a>的工具，只不过比起通配符，它能更精确地描述你的需求——当然，代价就是更复杂——比如你可以编写一个正则表达式，用来查找<span class=desc><u>所有以0开头，后面跟着2-3个数字，然后是一个连字号&#8220;-&#8221;，最后是7或8位数字的字符串</u></span>(像<span class=string><em>010-12345678</em></span>或<span class=string><em>0376-7654321</em></span>)。</p>
<p id=match>正则表达式是用于进行文本匹配的工具，所以本文里多次提到了在字符串里搜索/查找，这种说法的意思是在给定的字符串中，寻找与给定的正则表达式相匹配的部分。有可能字符串里有不止一个部分满足给定的正则表达式，这时每一个这样的部分被称为一个匹配。<span class=name><strong>匹配</strong></span>在本文里可能会有三种意思：一种是形容词性的，比如说一个字符串匹配一个表达式；一种是动词性的，比如说在字符串里匹配正则表达式；还有一种是名词性的，就是刚刚说到的&#8220;字符串中满足给定的正则表达式的一部分&#8221;。</p>
<h2 id=getstarted>入门</h2>
<p>学习正则表达式的最好方法是从例子开始，理解例子之后再自己对例子进行修改，实验。下面给出了不少简单的例子，并对它们作了详细的说明。</p>
<p>假设你在一篇英文小说里查找<span class=desc><u>hi</u></span>，你可以使用正则表达式<span class=regex><font color=#ff0000>hi</font></span>。</p>
<p>这是最简单的正则表达式了，它可以精确匹配这样的字符串：<span class=desc><u>由两个字符组成，前一个字符是h,后一个是i</u></span>。通常，处理正则表达式的工具会提供一个忽略大小写的选项，如果选中了这个选项，它可以匹配<span class=string><em>hi</em></span>,<span class=string><em>HI</em></span>,<span class=string><em>Hi</em></span>,<span class=string><em>hI</em></span>这四种情况中的任意一种。</p>
<p>不幸的是，很多单词里包含<span class=string><em>hi</em></span>这两个连续的字符，比如<span class=string><em>him</em></span>,<span class=string><em>history</em></span>,<span class=string><em>high</em></span>等等。用<span class=regex><font color=#ff0000>hi</font></span>来查找的话，这里边的<span class=string><em>hi</em></span>也会被找出来。如果要<span class=desc><u>精确地查找hi这个单词</u></span>的话，我们应该使用<span class=regex><font color=#ff0000>\bhi\b</font></span>。</p>
<p><span class=part><font color=#008000>\b</font></span>是正则表达式规定的一个特殊代码（好吧，某些人叫它<span class=name><strong>元字符，metacharacter</strong></span>），代表着<span class=desc><u>单词的开头或结尾，也就是单词的分界处</u></span>。虽然通常英文的单词是由空格或标点符号或换行来分隔的，但是<span class=code><font color=#0000ff>\b</font></span>并不匹配这些单词分隔符中的任何一个，它<strong>只匹配一个位置</strong>。（如果需要更精确的说法，<span class=code><font color=#0000ff>\b</font></span>匹配这样的位置：它的前一个字符和后一个字符不全是(一个是,一个不是或不存在)<span class=code><font color=#0000ff>\w</font></span>）</p>
<p>假如你要找的是<span class=desc><u>hi后面不远处跟着一个Lucy</u></span>，你应该用<span class=regex><font color=#ff0000>\bhi\b.*\bLucy\b</font></span>。</p>
<p>这里，<span class=part><font color=#008000>.</font></span>是另一个元字符，匹配<span class=desc><u>除了换行符以外的任意字符</u></span>。<span class=part><font color=#008000>*</font></span>同样是元字符，不过它代表的不是字符，也不是位置，而是数量——它指定*<span class=desc><u>前边的内容可以连续重复出现任意次以使整个表达式得到匹配</u></span>。因此，<span class=part><font color=#008000>.*</font></span>连在一起就意味着<span class=desc><u>任意数量的不包含换行的字符</u></span>。现在<span class=regex><font color=#ff0000>\bhi\b.*\bLucy\b</font></span>的意思就很明显了：<span class=desc><u>先是一个单词hi,然后是任意个任意字符(但不能是换行)，最后是Lucy这个单词</u></span>。</p>
<p>如果同时使用其它的一些元字符，我们就能构造出功能更强大的正则表达式。比如下面这个例子：</p>
<p><span class=regex><font color=#ff0000>0\d\d-\d\d\d\d\d\d\d\d</font></span>匹配这样的字符串：<span class=desc><u>以0开头，然后是两个数字，然后是一个连字号&#8220;-&#8221;，最后是8个数字</u></span>(也就是中国的电话号码。当然，这个例子只能匹配区号为3位的情形)。</p>
<p>这里的<span class=part><font color=#008000>\d</font></span>是一个新的元字符，匹配<span class=desc><u>任意的数字(0，或1，或2，或&#8230;&#8230;)</u></span>。<span class=part><font color=#008000>-</font></span>不是元字符，只匹配它本身——连字号。</p>
<p>为了避免那么多烦人的重复，我们也可以这样写这个表达式：<span class=regex><font color=#ff0000>0\d{2}-\d{8}</font></span>。 这里<span class=part><font color=#008000>\d</font></span>后面的<span class=part><font color=#008000>{2}</font></span>(<span class=part><font color=#008000>{8}</font></span>)的意思是前面<span class=part><font color=#008000>\d</font></span><span class=desc><u>必须连续重复匹配2次(8次)</u></span>。</p>
<h2 id=testing>测试正则表达式</h2>
<p>如果你不觉得正则表达式很难读写的话，要么你是一个天才，要么，你不是地球人。正则表达式的语法很令人头疼，即使对经常使用它的人来说也是如此。由于难于读写，容易出错，所以很有必要创建一种工具来测试正则表达式。</p>
<p>由于在不同的环境下正则表达式的一些细节是不相同的，本教程介绍的是Microsoft .Net 2.0下正则表达式的行为，所以，我向你介绍一个.Net下的工具<a title=转到RegexTester的官方网站（英文） href="http://www.dotnet2themax.com/blogs/fbalena/PermaLink,guid,13bce26d-7755-441e-92b3-1eb5f9e859f9.aspx"><u><font color=#0000ff>Regex Tester</font></u></a>。首先你确保已经安装了<a title="转到下载.Net Framework 2.0的页面" href="http://www.microsoft.com/downloads/details.aspx?displaylang=zh-cn&amp;FamilyID=0856eacb-4362-4b0d-8edd-aab15c5e04f5"><u><font color=#0000ff>.Net Framework 2.0</font></u></a>，然后<a title="从www.unibetter.com下载Regex Tester, 75KB" href="http://www.unibetter.com/deerchao/downloads/RegexTester.zip"><u><font color=#0000ff>下载Regex Tester</font></u></a>。这是个绿色软件，下载完后打开压缩包,直接运行RegexTester.exe就可以了。</p>
<p>下面是Regex Tester运行时的截图：</p>
<p><img alt="Regex Tester运行时的截图" src="http://www.unibetter.com/deerchao/images/RegexTester.jpg"></p>
<h2 id=metacode>元字符</h2>
<p>现在你已经知道几个很有用的元字符了，如<span class=code><font color=#0000ff>\b</font></span>,<span class=code><font color=#0000ff>.</font></span>,<span class=code><font color=#0000ff>*</font></span>，还有<span class=code><font color=#0000ff>\d</font></span>.当然还有更多的元字符可用，比如<span class=code><font color=#0000ff>\s</font></span>匹配<span class=desc><u>任意的空白符，包括空格，制表符(Tab)，换行符，中文全角空格等</u></span>。<span class=code><font color=#0000ff>\w</font></span>匹配<span class=desc><u>字母或数字或下划线或汉字等</u></span>。</p>
<p>下面来试试更多的例子：</p>
<p><span class=regex><font color=#ff0000>\ba\w*\b</font></span>匹配<span class=desc><u>以字母<span class=part><font color=#008000>a</font></span>开头的单词——先是某个单词开始处(<span class=part><font color=#008000>\b</font></span>)，然后是字母<span class=part><font color=#008000>a</font></span>,然后是任意数量的字母或数字(<span class=part><font color=#008000>\w*</font></span>)，最后是单词结束处(<span class=part><font color=#008000>\b</font></span>)</u></span>（好吧，现在我们说说正则表达式里的单词是什么意思吧：就是几个连续的<span class=code><font color=#0000ff>\w</font></span>。不错，这与学习英文时要背的成千上万个同名的东西的确关系不大）。</p>
<p><span class=regex><font color=#ff0000>\d+</font></span>匹配<span class=desc><u>1个或更多连续的数字</u></span>。这里的<span class=part><font color=#008000>+</font></span>是和<span class=code><font color=#0000ff>*</font></span>类似的元字符，不同的是<span class=code><font color=#0000ff>*</font></span>匹配<span class=desc><u>重复任意次(可能是0次)</u></span>，而<span class=code><font color=#0000ff>+</font></span>则匹配<span class=desc><u>重复1次或更多次</u></span>。</p>
<p><span class=regex><font color=#ff0000>\b\w{6}\b</font></span> 匹配<span class=desc><u>刚好6个字母/数字的单词</u></span>。</p>
<table cellSpacing=0>
    <caption>表1.常用的元字符</caption>
    <tbody>
        <tr>
            <th>代码</th>
            <th>说明</th>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>.</font></span></td>
            <td><span class=desc><u>匹配除换行符以外的任意字符</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>\w</font></span></td>
            <td><span class=desc><u>匹配字母或数字或下划线或汉字</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>\s</font></span></td>
            <td><span class=desc><u>匹配任意的空白符</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>\d</font></span></td>
            <td><span class=desc><u>匹配数字</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>\b</font></span></td>
            <td><span class=desc><u>匹配单词的开始或结束</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>^</font></span></td>
            <td><span class=desc><u>匹配字符串的开始</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>$</font></span></td>
            <td><span class=desc><u>匹配字符串的结束</u></span></td>
        </tr>
    </tbody>
</table>
<p>元字符<span class=code><font color=#0000ff>^</font></span>（和数字6在同一个键位上的符号）以及<span class=code><font color=#0000ff>$</font></span>和<span class=code><font color=#0000ff>\b</font></span>有点类似，都匹配一个位置。<span class=code><font color=#0000ff>^</font></span>匹配你要用来查找的字符串的开头，<span class=code><font color=#0000ff>$</font></span>匹配结尾。这两个代码在验证输入的内容时非常有用，比如一个网站如果要求你填写的QQ号必须为5位到12位数字时，可以使用：<span class=regex><font color=#ff0000>^\d{5,12}$</font></span>。</p>
<p>这里的<span class=part><font color=#008000>{5,12}</font></span>和前面介绍过的<span class=part><font color=#008000>{2}</font></span>是类似的，只不过<span class=part><font color=#008000>{2}</font></span>匹配<span class=desc><u>只能不多不少重复2次</u></span>，<span class=part><font color=#008000>{5,12}</font></span>则是<span class=desc><u>重复的次数不能少于5次，不能多于12次</u></span>，否则都不匹配。</p>
<p>因为使用了<span class=part><font color=#008000>^</font></span>和<span class=part><font color=#008000>$</font></span>，所以输入的整个字符串都要用来和<span class=part><font color=#008000>\d{5,12}</font></span>来匹配，也就是说整个输入<span class=desc><u>必须是5到12个数字</u></span>，因此如果输入的QQ号能匹配这个正则表达式的话，那就符合要求了。</p>
<p>和忽略大小写的选项类似，有些正则表达式处理工具还有一个处理多行的选项。如果选中了这个选项，<span class=code><font color=#0000ff>^</font></span>和<span class=code><font color=#0000ff>$</font></span>的意义就变成了<span class=desc><u>匹配行的开始处和结束处</u></span>。</p>
<h2 id=escape>字符转义</h2>
<p>如果你想查找元字符本身的话，比如你查找<span class=desc><u>.</u></span>,或者<span class=desc><u>*</u></span>,就出现了问题：你没法指定它们，因为它们会被解释成其它的意思。这时你就必须使用<span class=code><font color=#0000ff>\</font></span>来取消这些字符的特殊意义。因此，你应该使用<span class=regex><font color=#ff0000>\.</font></span>和<span class=regex><font color=#ff0000>\*</font></span>。当然，要查找<span class=desc><u>\</u></span>本身，你也得用<span class=regex><font color=#ff0000>\\</font></span>.</p>
<p>例如：<span class=regex><font color=#ff0000>www\.unibetter\.com</font></span>匹配<span class=desc><u>www.unibetter.com</u></span>，<span class=regex><font color=#ff0000>c:\\Windows</font></span>匹配<span class=desc><u>c:\Windows</u></span>。</p>
<h2 id=repeat>重复</h2>
<p>你已经看过了前面的<span class=code><font color=#0000ff>*</font></span>,<span class=code><font color=#0000ff>+</font></span>,<span class=code><font color=#0000ff>{2}</font></span>,<span class=code><font color=#0000ff>{5,12}</font></span>这几个匹配重复的方式了。下面是正则表达式中所有的限定符(指定数量的代码，例如*,{5,12}等)：</p>
<table cellSpacing=0>
    <caption>表2.常用的限定符</caption>
    <tbody>
        <tr>
            <th>代码/语法</th>
            <th>说明</th>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>*</font></span></td>
            <td><span class=desc><u>重复零次或更多次</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>+</font></span></td>
            <td><span class=desc><u>重复一次或更多次</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>?</font></span></td>
            <td><span class=desc><u>重复零次或一次</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>{n}</font></span></td>
            <td><span class=desc><u>重复n次</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>{n,}</font></span></td>
            <td><span class=desc><u>重复n次或更多次</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>{n,m}</font></span></td>
            <td><span class=desc><u>重复n到m次</u></span></td>
        </tr>
    </tbody>
</table>
<p>下面是一些使用重复的例子：</p>
<p><span class=regex><font color=#ff0000>Windows\d+</font></span>匹配<span class=desc><u>Windows后面跟1个或更多数字</u></span></p>
<p><span class=regex><font color=#ff0000>13\d{9}</font></span>匹配<span class=desc><u>13后面跟9个数字(中国的手机号)</u></span></p>
<p><span class=regex><font color=#ff0000>^\w+</font></span>匹配<span class=desc><u>一行的第一个单词(或整个字符串的第一个单词，具体匹配哪个意思得看选项设置)</u></span></p>
<h2 id=charclass>字符类</h2>
<p>要想查找数字，字母或数字，空白是很简单的，因为已经有了对应这些字符集合的元字符，但是如果你想匹配没有预定义元字符的字符集合(比如元音字母a,e,i,o,u),应该怎么办？</p>
<p>很简单，你只需要在中括号里列出它们就行了，像<span class=regex><font color=#ff0000>[aeiou]</font></span>就匹配<span class=desc><u>任何一个英文元音字母</u></span>，<span class=regex><font color=#ff0000>[.?!]</font></span>匹配<span class=desc><u>标点符号(.或?或!)</u></span>(英文语句通常只以这三个标点结束)。</p>
<p>我们也可以轻松地指定一个字符<span class=name><strong>范围</strong></span>，像<span class=regex><font color=#ff0000>[0-9]</font></span>代表的含意与<span class=regex><font color=#ff0000>\d</font></span>就是完全一致的：<span class=desc><u>一位数字</u></span>，同理<span class=regex><font color=#ff0000>[a-z0-9A-Z_]</font></span>也完全等同于<span class=code><font color=#0000ff>\w</font></span>（如果只考虑英文的话）。</p>
<p>下面是一个更复杂的表达式：<span class=regex><font color=#ff0000>\(?0\d{2}[) -]?\d{8}</font></span>。</p>
<p>这个表达式可以匹配<span class=desc><u>几种格式的电话号码</u></span>，像<span class=string><em>(010)88886666</em></span>，或<span class=string><em>022-22334455</em></span>，或<span class=string><em>02912345678</em></span>等。我们对它进行一些分析吧：首先是一个转义字符<span class=part><font color=#008000>\(</font></span>,它能出现0次或1次(<span class=part><font color=#008000>?</font></span>),然后是一个<span class=part><font color=#008000>0</font></span>，后面跟着2个数字(<span class=part><font color=#008000>\d{2}</font></span>)，然后是<span class=part><font color=#008000>)</font></span>或<span class=part><font color=#008000>-</font></span>或<span class=part><font color=#008000>空格</font></span>中的一个，它出现1次或不出现(<span class=part><font color=#008000>?</font></span>)，最后是8个数字(<span class=part><font color=#008000>\d{8}</font></span>)。不幸的是，它也能匹配<span class=string><em>010)12345678</em></span>或<span class=string><em>(022-87654321</em></span>这样的&#8220;不正确&#8221;的格式。要解决这个问题，请在本教程的下面查找答案。</p>
<h2 id=negation>反义</h2>
<p>有时需要查找不属于某个能简单定义的字符类的字符。比如想查找除了数字以外，其它任意字符都行的情况，这时需要用到<span class=name><strong>反义</strong></span>：</p>
<table cellSpacing=0>
    <caption>表3.常用的反义代码</caption>
    <tbody>
        <tr>
            <th>代码/语法</th>
            <th>说明</th>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>\W</font></span></td>
            <td><span class=desc><u>匹配任意不是字母，数字，下划线，汉字的字符</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>\S</font></span></td>
            <td><span class=desc><u>匹配任意不是空白符的字符</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>\D</font></span></td>
            <td><span class=desc><u>匹配任意非数字的字符</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>\B</font></span></td>
            <td><span class=desc><u>匹配不是单词开头或结束的位置</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>[^x]</font></span></td>
            <td><span class=desc><u>匹配除了x以外的任意字符</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>[^aeiou]</font></span></td>
            <td><span class=desc><u>匹配除了aeiou这几个字母以外的任意字符</u></span></td>
        </tr>
    </tbody>
</table>
<p>例子：<span class=regex><font color=#ff0000>\S+</font></span>匹配<span class=desc><u>不包含空白符的字符串</u></span>。</p>
<p><span class=regex><font color=#ff0000>&lt;a[^&gt;]+&gt;</font></span>匹配<span class=desc><u>用尖括号括起来的以a开头的字符串</u></span>。</p>
<h2 id=alternative>替换</h2>
<p>好了，现在终于到了解决3位或4位区号问题的时间了。正则表达式里的<span class=name><strong>替换</strong></span>指的是有几种规则，如果满足其中任意一种规则都应该当成匹配，具体方法是用<span class=code><font color=#0000ff>|</font></span>把不同的规则分隔开。听不明白？没关系，看例子：</p>
<p><span class=regex><font color=#ff0000>0\d{2}-\d{8}|0\d{3}-\d{7}</font></span>这个表达式能<span class=desc><u>匹配两种以连字号分隔的电话号码：一种是三位区号，8位本地号(如010-12345678)，一种是4位区号，7位本地号(0376-2233445)</u></span>。</p>
<p><span class=regex><font color=#ff0000>\(0\d{2}\)[- ]?\d{8}|0\d{2}[- ]?\d{8}</font></span>这个表达式<span class=desc><u>匹配3位区号的电话号码，其中区号可以用小括号括起来，也可以不用，区号与本地号间可以用连字号或空格间隔，也可以没有间隔</u></span>。你可以试试用替换|把这个表达式扩展成也支持4位区号的。</p>
<p><span class=regex><font color=#ff0000>\d{5}-\d{4}|\d{5}</font></span>这个表达式用于匹配美国的邮政编码。美国邮编的规则是5位数字，或者用连字号间隔的9位数字。之所以要给出这个例子是因为它能说明一个问题：<strong>使用替换时，顺序是很重要的</strong>。如果你把它改成<span class=regex><font color=#ff0000>\d{5}|\d{5}-\d{4}</font></span>的话，那么就只会匹配5位的邮编(以及9位邮编的前5位)。原因是匹配替换时，将会从左到右地测试每个分枝条件，如果满足了某个分枝的话，就不会去管其它的替换条件了。</p>
<p><span class=regex><font color=#ff0000>Windows98|Windows2000|WindosXP</font></span>这个例子是为了告诉你替换不仅仅能用于两种规则，也能用于更多种规则。</p>
<h2 id=grouping>分组</h2>
<p>我们已经提到了怎么重复单个字符（直接在字符后面加上限定符就行了）；但如果想要重复多个字符又该怎么办？你可以用小括号来指定<span class=name><strong>子表达式</strong></span>(也叫做<span class=name><strong>分组</strong></span>)，然后你就可以指定这个子表达式的重复次数了，你也可以对子表达式进行其它一些操作(后面会有介绍)。</p>
<p><span class=regex><font color=#ff0000>(\d{1,3}\.){3}\d{1,3}</font></span>是一个<span class=desc><u>简单的IP地址匹配</u></span>表达式。要理解这个表达式，请按下列顺序分析它：<span class=part><font color=#008000>\d{1,3}</font></span>匹配<span class=desc><u>1到3位的数字</u></span>，<span class=part><font color=#008000>(\d{1,3}\.}{3}</font></span>匹配<span class=desc><u>三位数字加上一个英文句号(这个整体也就是这个<span class=name><strong>分组</strong></span>)重复3次</u></span>，最后再加上<span class=desc><u>一个一到三位的数字</u></span>(<span class=part><font color=#008000>\d{1,3}</font></span>)。</p>
<p>不幸的是，它也将匹配<span class=string><em>256.300.888.999</em></span>这种不可能存在的IP地址(IP地址中每个数字都不能大于255。题外话，好像反恐24小时第三季的编剧不知道这一点，汗...)。如果能使用算术比较的话，或许能简单地解决这个问题，但是正则表达式中并不提供关于数学的任何功能，所以只能使用冗长的分组，选择，字符类来描述一个正确的IP地址：<span class=regex><font color=#ff0000>((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)</font></span>。</p>
<p>理解这个表达式的关键是理解<span class=part><font color=#008000>2[0-4]\d|25[0-5]|[01]?\d\d?</font></span>，这里我就不细说了，你自己应该能分析得出来它的意义。</p>
<h2 id=backreference>后向引用</h2>
<p>使用小括号指定一个子表达式后，<strong>匹配这个子表达式的文本</strong>(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。默认情况下，每个分组会自动拥有一个<span class=name><strong>组号</strong></span>，规则是：从左向右，以分组的左括号为标志，第一个出现的分组的组号为1，第二个为2，以此类推。</p>
<p><span class=name><strong>后向引用</strong></span>用于重复搜索前面某个分组匹配的文本。例如，<span class=part><font color=#008000>\1</font></span>代表<span class=desc><u>分组1匹配的文本</u></span>。难以理解？请看示例：</p>
<p><span class=regex><font color=#ff0000>\b(\w+)\b\s+\1\b</font></span>可以用来匹配<span class=desc><u>重复的单词</u></span>，像<span class=string><em>go go</em></span>, <span class=string><em>kitty kitty</em></span>。首先是<span class=desc><u>一个单词</u></span>，也就是<span class=desc><u>单词开始处和结束处之间的多于一个的字母或数字</u></span>(<span class=part><font color=#008000>\b(\w+)\b</font></span>)，然后是<span class=desc><u>1个或几个空白符</u></span>(<span class=part><font color=#008000>\s+</font></span>)，最后是<span class=desc><u>前面匹配的那个单词</u></span>(<span class=part><font color=#008000>\1</font></span>)。</p>
<p>你也可以自己指定子表达式的<span class=name><strong>组名</strong></span>。要指定一个子表达式的组名，请使用这样的语法：<span class=code><font color=#0000ff>(?&lt;Word&gt;\w+)</font></span>(或者把尖括号换成<span class=code><font color=#0000ff>'</font></span>也行：<span class=code><font color=#0000ff>(?'Word'\w+)</font></span>),这样就把<span class=part><font color=#008000>\w+</font></span>的组名指定为<span class=part><font color=#008000>Word</font></span>了。要反向引用这个分组<span class=name><strong>捕获</strong></span>的内容，你可以使用<span class=code><font color=#0000ff>\k&lt;Word&gt;</font></span>,所以上一个例子也可以写成这样：<span class=regex><font color=#ff0000>\b(?&lt;Word&gt;\w+)\b\s+\k&lt;Word&gt;\b</font></span>。</p>
<p>使用小括号的时候，还有很多特定用途的语法。下面列出了最常用的一些：</p>
<table cellSpacing=0>
    <caption>表4.分组语法</caption>
    <tbody>
        <tr>
            <th colSpan=2>捕获</th>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>(exp)</font></span></td>
            <td><span class=desc><u>匹配exp,并捕获文本到自动命名的组里</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>(?&lt;name&gt;exp)</font></span></td>
            <td><span class=desc><u>匹配exp,并捕获文本到名称为name的组里，也可以写成(?'name'exp)</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>(?:exp)</font></span></td>
            <td><span class=desc><u>匹配exp,不捕获匹配的文本，也不给此分组分配组号</u></span></td>
        </tr>
        <tr>
            <th colSpan=2>零宽断言</th>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>(?=exp)</font></span></td>
            <td><span class=desc><u>匹配exp前面的位置</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>(?&lt;=exp)</font></span></td>
            <td><span class=desc><u>匹配exp后面的位置</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>(?!exp)</font></span></td>
            <td><span class=desc><u>匹配后面跟的不是exp的位置</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>(?&lt;!exp)</font></span></td>
            <td><span class=desc><u>匹配前面不是exp的位置</u></span></td>
        </tr>
        <tr>
            <th colSpan=2>注释</th>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>(?#comment)</font></span></td>
            <td><span class=desc><u>这种类型的组不对正则表达式的处理产生任何影响，用于提供注释让人阅读</u></span></td>
        </tr>
    </tbody>
</table>
<p>我们已经讨论了前两种语法。第三个<span class=code><font color=#0000ff>(?:exp)</font></span>不会改变正则表达式的处理方式，只是这样的组匹配的内容<span class=desc><u>不会像前两种那样被捕获到某个组里面</u></span>。</p>
<h2 id=lookaround>零宽断言</h2>
<p>接下来的四个用于查找在某些内容(但并不包括这些内容)之前或之后的东西，也就是说它们像<span class=code><font color=#0000ff>\b</font></span>,<span class=code><font color=#0000ff>^</font></span>,<span class=code><font color=#0000ff>$</font></span>那样用于指定一个位置，这个位置应该满足一定的条件(<a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#reference"><u><font color=#800080>断言</font></u></a>)，因此它们也被称为<span class=name><strong>零宽断言</strong></span>。最好还是拿例子来说明吧：</p>
<p><span class=code><font color=#0000ff>(?=exp)</font></span>也叫<span class=name><strong>零宽度正预测先行断言</strong></span>，它<span class=desc><u>断言自身出现的位置的后面能匹配表达式exp</u></span>。比如<span class=regex><font color=#ff0000>\b\w+(?=ing\b)</font></span>，匹配<span class=desc><u>以ing结尾的单词的前面部分(除了ing以外的部分)</u></span>，如查找<span class=string><em>I'm singing while you're dancing.</em></span>时，它会匹配<span class=desc><u>sing</u></span>和<span class=desc><u>danc</u></span>。</p>
<p><span class=code><font color=#0000ff>(?&lt;=exp)</font></span>也叫<span class=name><strong>零宽度正回顾后发断言</strong></span>，它<span class=desc><u>断言自身出现的位置的前面能匹配表达式exp</u></span>。比如<span class=regex><font color=#ff0000>(?&lt;=\bre)\w+\b</font></span>会匹配<span class=desc><u>以re开头的单词的后半部分(除了re以外的部分)</u></span>，例如在查找<span class=string><em>reading a book</em></span>时，它匹配<span class=desc><u>ading</u></span>。</p>
<p>假如你想要给一个很长的数字中每三位间加一个逗号(当然是从右边加起了)，你可以这样查找需要在前面和里面添加逗号的部分：<span class=regex><font color=#ff0000>((?&lt;=\d)\d{3})*\b</font></span>，用它对<span class=string><em>1234567890</em></span>进行查找时结果是<span class=desc><u>234567890</u></span>。</p>
<p>下面这个例子同时使用了这两种断言：<span class=regex><font color=#ff0000>(?&lt;=\s)\d+(?=\s)</font></span>匹配<span class=desc><u>以空白符间隔的数字(再次强调，不包括这些空白符)</u></span>。</p>
<h2 id=negativelookaround>负向零宽断言</h2>
<p>前面我们提到过怎么查找<strong>不是某个字符或不在某个字符类里</strong>的字符的方法(反义)。但是如果我们只是想要<strong>确保某个字符没有出现，但并不想去匹配它</strong>时怎么办？例如，如果我们想查找这样的单词--它里面出现了字母q,但是q后面跟的不是字母u,我们可以尝试这样：</p>
<p><span class=regex><font color=#ff0000>\b\w*q[^u]\w*\b</font></span>匹配<span class=desc><u>包含<strong>后面不是字母u的字母q</strong>的单词</u></span>。但是如果多做测试(或者你思维足够敏锐，直接就观察出来了)，你会发现，如果q出现在单词的结尾的话，像<strong>Iraq</strong>,<strong>Benq</strong>，这个表达式就会出错。这是因为<span class=part><font color=#008000>[^u]</font></span>总要匹配一个字符，所以如果q是单词的最后一个字符的话，后面的<span class=part><font color=#008000>[^u]</font></span>将会匹配q后面的单词分隔符(可能是空格，或者是句号或其它的什么)，后面的<span class=part><font color=#008000>\w*\b</font></span>将会匹配下一个单词，于是<span class=regex><font color=#ff0000>\b\w*q[^u]\w*\b</font></span>就能匹配整个<span class=string><em>Iraq fighting</em></span>。<span class=name><strong>负向零宽断言</strong></span>能解决这样的问题，因为它只匹配一个位置，并不<strong>消费</strong>任何字符。现在，我们可以这样来解决这个问题：<span class=regex><font color=#ff0000>\b\w*q(?!u)\w*\b</font></span>。</p>
<p><span class=name><strong>零宽度负预测先行断言</strong></span><span class=code><font color=#0000ff>(?!exp)</font></span>，<span class=desc><u>断言此位置的后面不能匹配表达式exp</u></span>。例如：<span class=regex><font color=#ff0000>\d{3}(?!\d)</font></span>匹配<span class=desc><u>三位数字，而且这三位数字的后面不能是数字</u></span>；<span class=regex><font color=#ff0000>\b((?!abc)\w)+\b</font></span>匹配<span class=desc><u>不包含连续字符串abc的单词</u></span>。</p>
<p>同理，我们可以用<span class=code><font color=#0000ff>(?&lt;!exp)</font></span>,<span class=name><strong>零宽度正回顾后发断言</strong></span>来<span class=desc><u>断言此位置的前面不能匹配表达式exp</u></span>：<span class=regex><font color=#ff0000>(?&lt;![a-z])\d{7}</font></span>匹配<span class=desc><u>前面不是小写字母的七位数字</u></span>。</p>
<p>一个更复杂的例子：<span class=regex><font color=#ff0000>(?&lt;=&lt;(\w+)&gt;).*(?=&lt;\/\1&gt;)</font></span>匹配<span class=desc><u>不包含属性的简单HTML标签内里的内容</u></span>。<span class=code><font color=#0000ff>(&lt;?(\w+)&gt;)</font></span>指定了这样的<span class=name><strong>前缀</strong></span>：<span class=desc><u>被尖括号括起来的单词</u></span>(比如可能是&lt;b&gt;)，然后是<span class=part><font color=#008000>.*</font></span>(任意的字符串),最后是一个<span class=name><strong>后缀</strong></span><span class=part><font color=#008000>(?=&lt;\/\1&gt;)</font></span>。注意后缀里的<span class=part><font color=#008000>\/</font></span>，它用到了前面提过的字符转义；<span class=part><font color=#008000>\1</font></span>则是一个反向引用，引用的正是<span class=desc><u>捕获的第一组</u></span>，前面的<span class=part><font color=#008000>(\w+)</font></span>匹配的内容，这样如果前缀实际上是&lt;b&gt;的话，后缀就是&lt;/b&gt;了。整个表达式匹配的是&lt;b&gt;和&lt;/b&gt;之间的内容(再次提醒，不包括前缀和后缀本身)。</p>
<h2 id=commenting>注释</h2>
<p>小括号的另一种用途是能过语法<span class=code><font color=#0000ff>(?#comment)</font></span>来包含注释。例如：<span class=regex><font color=#ff0000>2[0-4]\d(?#200-249)|25[0-5](?#250-255)|[01]?\d\d?(?#0-199)</font></span>。</p>
<p>要包含注释的话，最好是启用&#8220;忽略模式里的空白符&#8221;选项，这样在编写表达式时能任意的添加空格，Tab，换行，而实际使用时这些都将被忽略。启用这个选项后，在#后面到这一行结束的所有文本都将被当成注释忽略掉。</p>
<p>例如，我们可以前面的一个表达式写成这样：</p>
<pre class=regex>      (?&lt;=    # 断言要匹配的文本的前缀
&lt;(\w+)&gt; # 查找尖括号括起来的字母或数字(即HTML/XML标签)
)       # 前缀结束
.*      # 匹配任意文本
(?=     # 断言要匹配的文本的后缀
&lt;\/\1&gt;  # 查找尖括号括起来的内容：前面是一个"/"，后面是先前捕获的标签
)       # 后缀结束
</pre>
<h2 id=greedyandlazy>贪婪与懒惰</h2>
<p>当正则表达式中包含能接受重复的限定符时，通常的行为是（在使整个表达式能得到匹配的前提下）匹配<strong>尽可能多</strong>的字符。考虑这个表达式：<span class=regex><font color=#ff0000>a.*b</font></span>，它将会匹配<span class=desc><u>最长的以a开始，以b结束的字符串</u></span>。如果用它来搜索<span class=string><em>aabab</em></span>的话，它会匹配整个字符串<span class=desc><u>aabab</u></span>。这被称为<span class=name><strong>贪婪</strong></span>匹配。</p>
<p>有时，我们更需要<span class=name><strong>懒惰</strong></span>匹配，也就是匹配<strong>尽可能少</strong>的字符。前面给出的限定符都可以被转化为懒惰匹配模式，只要在它后面加上一个问号<span class=code><font color=#0000ff>?</font></span>。这样<span class=regex><font color=#ff0000>.*?</font></span>就意味着<span class=desc><u>匹配任意数量的重复，但是在能使整个匹配成功的前提下使用最少的重复</u></span>。现在看看懒惰版的例子吧：</p>
<p><span class=regex><font color=#ff0000>a.*?b</font></span>匹配<span class=desc><u>最短的，以a开始，以b结束的字符串</u></span>。如果把它应用于<span class=string><em>aabab</em></span>的话，它会匹配<span class=desc><u>aab</u></span>和<span class=desc><u>ab</u></span>（为什么第一个匹配是aab而不是ab？简单地说，因为正则表达式有另一条规则，比懒惰／贪婪规则的优先级更高：最先开始的匹配最有最大的优先权——The Match That Begins Earliest Wins）。</p>
<table cellSpacing=0>
    <caption>表5.懒惰限定符</caption>
    <tbody>
        <tr>
            <td><span class=code><font color=#0000ff>*?</font></span></td>
            <td><span class=desc><u>重复任意次，但尽可能少重复</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>+?</font></span></td>
            <td><span class=desc><u>重复1次或更多次，但尽可能少重复</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>??</font></span></td>
            <td><span class=desc><u>重复0次或1次，但尽可能少重复</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>{n,m}?</font></span></td>
            <td><span class=desc><u>重复n到m次，但尽可能少重复</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>{n,}?</font></span></td>
            <td><span class=desc><u>重复n次以上，但尽可能少重复</u></span></td>
        </tr>
    </tbody>
</table>
<h2 id=regexoptions>处理选项</h2>
<p>上面介绍了几个选项如忽略大小写，处理多行等，这些选项能用来改变处理正则表达式的方式。下面是.Net中常用的正则表达式选项：</p>
<table cellSpacing=0>
    <caption>表6.常用的处理选项</caption>
    <thead>
        <tr>
            <th>名称</th>
            <th>说明</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>IgnoreCase(忽略大小写)</td>
            <td>匹配时不区分大小写。</td>
        </tr>
        <tr>
            <td>Multiline(多行模式)</td>
            <td>更改<span class=code><font color=#0000ff>^</font></span>和<span class=code><font color=#0000ff>$</font></span>的含义，使它们分别在任意一行的行首和行尾匹配，而不仅仅在整个字符串的开头和结尾匹配。(在此模式下,<span class=code><font color=#0000ff>$</font></span>的精确含意是:匹配\n之前的位置以及字符串结束前的位置.) </td>
        </tr>
        <tr>
            <td>Singleline(单行模式)</td>
            <td>更改<span class=code><font color=#0000ff>.</font></span>的含义，使它与每一个字符匹配（包括换行符\n）。 </td>
        </tr>
        <tr>
            <td>IgnorePatternWhitespace(忽略空白)</td>
            <td>忽略表达式中的非转义空白并启用由<span class=code><font color=#0000ff>#</font></span>标记的注释。</td>
        </tr>
        <tr>
            <td>RightToLeft(从右向左查找)</td>
            <td>匹配从右向左而不是从左向右进行。</td>
        </tr>
        <tr>
            <td>ExplicitCapture(显式捕获)</td>
            <td>仅捕获已被显式命名的组。</td>
        </tr>
        <tr>
            <td>ECMAScript(JavaScript兼容模式)</td>
            <td>使表达式的行为与它在JavaScript里的行为一致。</td>
        </tr>
    </tbody>
</table>
<p>一个经常被问到的问题是：是不是只能同时使用多行模式和单行模式中的一种？答案是：不是。这两个选项之间没有任何关系，除了它们的名字比较相似（以至于让人感到疑惑）以外。</p>
<h2 id=balancedgroup>平衡组/递归匹配</h2>
<p class=important>注意：这里介绍的平衡组语法是由.Net Framework支持的；其它语言／库不一定支持这种功能，或者支持此功能但需要使用不同的语法。 </p>
<p>有时我们需要匹配像<span class=desc><u>( 100 * ( 50 + 15 ) )这样的可嵌套的层次性结构</u></span>，这时简单地使用<span class=code><font color=#0000ff>\(.+\)</font></span>则只会匹配到最左边的左括号和最右边的右括号之间的内容(这里我们讨论的是贪婪模式，懒惰模式也有下面的问题)。假如原来的字符串里的左括号和右括号出现的次数不相等，比如<span class=string><em>( 5 / ( 3 + 2 ) ) )</em></span>，那我们的匹配结果里两者的个数也不会相等。有没有办法在这样的字符串里匹配到最长的，配对的括号之间的内容呢？ </p>
<p>为了避免<span class=code><font color=#0000ff>(</font></span>和<span class=code><font color=#0000ff>\(</font></span>把你的大脑彻底搞糊涂，我们还是用尖括号代替圆括号吧。现在我们的问题变成了如何把<span class=string><em>xx &lt;aa &lt;bbb&gt; &lt;bbb&gt; aa&gt; yy</em></span>这样的字符串里，最长的配对的尖括号内的内容捕获出来？ </p>
<p>这里需要用到以下的语法构造：</p>
<ul>
    <li><span class=code><font color=#0000ff>(?'group')</font></span> 把捕获的内容命名为group,并压入堆栈
    <li><span class=code><font color=#0000ff>(?'-group')</font></span> 从堆栈上弹出最后压入堆栈的名为group的捕获内容，如果堆栈本来为空，则本分组的匹配失败
    <li><span class=code><font color=#0000ff>(?(group)yes|no)</font></span> 如果堆栈上存在以名为group的捕获内容的话，继续匹配yes部分的表达式，否则继续匹配no部分
    <li><span class=code><font color=#0000ff>(?!)</font></span> 零宽负向先行断言，由于没有后缀表达式，试图匹配总是失败 </li>
</ul>
<p>如果你不是一个程序员（或者你是一个对堆栈的概念不熟的程序员），你就这样理解上面的三种语法吧：第一个就是在黑板上写一个 "group"，第二个就是从黑板上擦掉一个"group"，第三个就是看黑板上写的还有没有"group"，如果有就继续匹配yes部分，否则就匹配 no部分。</p>
<p>我们需要做的是每碰到了左括号，就在黑板上写一个"group"，每碰到一个右括号，就擦掉一个，到了最后就看看黑板上还有没有－－如果有那就证明左括号比右括号多，那匹配就应该失败。 </p>
<pre class=regex>&lt;                         #最外层的左括号
[^&lt;&gt;]*                #最外层的左括号后面的不是括号的内容
(
(
(?'Open'&lt;)    #碰到了左括号，在黑板上写一个"Open"
[^&lt;&gt;]*       #匹配左括号后面的不是括号的内容
)+
(
(?'-Open'&gt;)   #碰到了右括号，擦掉一个"Open"
[^&lt;&gt;]*        #匹配右括号后面不是括号的内容
)+
)*
(?(Open)(?!))         #在遇到最外层的右括号前面，判断黑板上还有没有没擦掉的"Open"；如果还有，则匹配失败
&gt;                         #最外层的右括号</pre>
<p>平衡组的一个最常见的应用就是匹配HTML,下面这个例子可以匹配<span class=desc><u>嵌套的&lt;div&gt;标签</u></span>：<span class=regex><font color=#ff0000>&lt;div[^&gt;]*&gt;[^&lt;&gt;]*(((?'Open'&lt;div[^&gt;]*&gt;)[^&lt;&gt;]*)+((?'-Open'&lt;/div&gt;)[^&lt;&gt;]*)+)*(?(Open)(?!))&lt;/div&gt;</font></span>.</p>
<h2 id=more>还有些什么东西没提到</h2>
<p>我已经描述了构造正则表达式的大量元素，还有一些我没有提到的东西。下面是未提到的元素的列表，包含语法和简单的说明。你可以在网上找到更详细的参考资料来学习它们--当你需要用到它们的时候。如果你安装了MSDN Library,你也可以在里面找到关于.net下正则表达式详细的文档。</p>
<table cellSpacing=0>
    <caption>表7.尚未详细讨论的语法</caption>
    <tbody>
        <tr>
            <td><span class=code><font color=#0000ff>\a</font></span></td>
            <td><span class=desc><u>报警字符(打印它的效果是电脑嘀一声)</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>\b</font></span></td>
            <td><span class=desc><u>通常是单词分界位置，但如果在字符类里使用代表退格</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>\t</font></span></td>
            <td><span class=desc><u>制表符，Tab</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>\r</font></span></td>
            <td><span class=desc><u>回车</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>\v</font></span></td>
            <td><span class=desc><u>竖向制表符</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>\f</font></span></td>
            <td><span class=desc><u>换页符</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>\n</font></span></td>
            <td><span class=desc><u>换行符</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>\e</font></span></td>
            <td><span class=desc><u>Escape</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>\0nn</font></span></td>
            <td><span class=desc><u>ASCII代码中八进制代码为nn的字符</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>\xnn</font></span></td>
            <td><span class=desc><u>ASCII代码中十六进制代码为nn的字符</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>\unnnn</font></span></td>
            <td><span class=desc><u>Unicode代码中十六进制代码为nnnn的字符</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>\cN</font></span></td>
            <td><span class=desc><u>ASCII控制字符。比如\cC代表Ctrl+C</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>\A</font></span></td>
            <td><span class=desc><u>字符串开头(类似^，但不受处理多行选项的影响)</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>\Z</font></span></td>
            <td><span class=desc><u>字符串结尾或行尾(不受处理多行选项的影响)</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>\z</font></span></td>
            <td><span class=desc><u>字符串结尾(类似$，但不受处理多行选项的影响)</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>\G</font></span></td>
            <td><span class=desc><u>当前搜索的开头</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>\p{name}</font></span></td>
            <td><span class=desc><u>Unicode中命名为name的字符类，例如\p{IsGreek}</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>(?&gt;exp)</font></span></td>
            <td><span class=desc><u>贪婪子表达式</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>(?&lt;x&gt;-&lt;y&gt;exp)</font></span></td>
            <td><span class=desc><u>平衡组</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>(?im-nsx:exp)</font></span></td>
            <td><span class=desc><u>在子表达式exp中改变处理选项</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>(?im-nsx)</font></span></td>
            <td><span class=desc><u>为表达式后面的部分改变处理选项</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>(?(exp)yes|no)</font></span></td>
            <td><span class=desc><u>把exp当作零宽正向先行断言，如果在这个位置能匹配，使用yes作为此组的表达式；否则使用no</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>(?(exp)yes)</font></span></td>
            <td><span class=desc><u>同上，只是使用空表达式作为no</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>(?(name)yes|no)</font></span></td>
            <td><span class=desc><u>如果命名为name的组捕获到了内容，使用yes作为表达式；否则使用no</u></span></td>
        </tr>
        <tr>
            <td><span class=code><font color=#0000ff>(?(name)yes)</font></span></td>
            <td><span class=desc><u>同上，只是使用空表达式作为no</u></span></td>
        </tr>
    </tbody>
</table>
<h2 id=contact>联系作者</h2>
<p>好吧,我承认,我骗了你,读到这里你肯定花了不止30分钟.相信我,这是我的错,而不是因为你太笨.我之所以说"30分钟",是为了让你有信心,有耐心继续下去.既然你看到了这里,那证明我的阴谋成功了.上这种当的滋味还不错吧?</p>
<p>要投诉我,或者觉得我其实可以做得更好,或者有任何其它问题,欢迎来<a href="http://www.cnblogs.com/deerchao/archive/2006/08/24/zhengzhe30fengzhongjiaocheng.html"><u><font color=#0000ff>我的博客</font></u></a>进行讨论.</p>
<h2 id=reference>一些我认为你可能已经知道的术语的参考</h2>
<dl>
<dt>字符
<dd>程序处理文字时最基本的单位，可能是字母，数字，标点符号，空格，换行符，汉字等等。
<dt>字符串
<dd>0个或更多个字符的序列。
<dt>文本
<dd>文字，字符串。
<dt>匹配
<dd>符合规则，检验是否符合规则，符合规则的部分。
<dt>断言
<dd>声明一个应该为真的事实。只有当断言为真时才会对正则表达式继续进行匹配。 </dd></dl>
<h2 id=resources>网上的资源及本文参考文献</h2>
<ul>
    <li><a href="http://msdn.microsoft.com/library/chs/default.asp?url=/library/CHS/jscript7/html/jsreconintroductiontoregularexpressions.asp"><u><font color=#0000ff>微软的正则表达式教程</font></u></a>
    <li><a href="http://msdn2.microsoft.com/zh-cn/library/system.text.regularexpressions.regex.aspx"><u><font color=#0000ff>System.Text.RegularExpressions.Regex类(MSDN)</font></u></a>
    <li><a href="http://www.regular-expressions.info/"><u><font color=#0000ff>专业的正则表达式教学网站(英文)</font></u></a>
    <li><a href="http://weblogs.asp.net/whaggard/archive/2005/02/20/377025.aspx"><u><font color=#0000ff>关于.Net下的平衡组的详细讨论（英文）</font></u></a>
    <li><a href="http://www.oreilly.com/catalog/regex2/"><u><font color=#0000ff>Mastering Regular Expressions (Second Edition)</font></u></a>
    <li><a href="http://validator.w3.org/check?uri=referer"><u><font color=#0000ff>Validated XHTML 1.0 Strict</font></u></a>
    <li><a href="http://jigsaw.w3.org/css-validator/check/referer"><u><font color=#0000ff>Validated CSS 2.1</font></u></a>
    <li><a href="http://www.mozilla.com/"><u><font color=#0000ff>推荐使用Mozilla FireFox浏览</font></u></a> </li>
</ul>
<h2 id=updatelog>更新说明</h2>
<ol>
    <li>2006-3-27 第一版
    <li>2006-10-12 第二版
    <ul>
        <li>修正了几个细节上的错误和不准确的地方
        <li>增加了对处理中文时的一些说明
        <li>更改了几个术语的翻译（采用了MSDN的翻译方式）
        <li>增加了平衡组的介绍
        <li>放弃了对The Regulator的介绍，改用Regex Tester </li>
    </ul>
    <li>2007-3-12 V2.1
    <ul>
        <li>修正了几个小的错误
        <li>增加了对处理选项(RegexOptions)的介绍 </li>
    </ul>
    <li>2007-5-28 V2.2
    <ul>
        <li>重新组织了对零宽断言的介绍
        <li>删除了几个不太合适的示例，添加了几个实用的示例
        <li>其它一些微小的更改 </li>
    </ul>
    <li>2007-8-3 V2.21
    <ul>
        <li>修改了几处文字错误
        <li>修改/添加了对$,\b的精确说明
        <li>承认了作者是个骗子
        <li>给RegexTester添加了Singleline选项的相关功能 </li>
    </ul>
    </li>
</ol>
<img src ="http://www.blogjava.net/yczz/aggbug/135351.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yczz/" target="_blank">飞鸟</a> 2007-08-08 21:16 <a href="http://www.blogjava.net/yczz/articles/135351.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>正则表达式之道</title><link>http://www.blogjava.net/yczz/articles/135350.html</link><dc:creator>飞鸟</dc:creator><author>飞鸟</author><pubDate>Wed, 08 Aug 2007 13:14:00 GMT</pubDate><guid>http://www.blogjava.net/yczz/articles/135350.html</guid><wfw:comment>http://www.blogjava.net/yczz/comments/135350.html</wfw:comment><comments>http://www.blogjava.net/yczz/articles/135350.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yczz/comments/commentRss/135350.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yczz/services/trackbacks/135350.html</trackback:ping><description><![CDATA[<center>
<h1>正则表达式之道</h1>
</center>
<center>
<p>
<hr width="100%">
<p>&#160;</p>
</center>
<h1><a name=WhatAreRegularExpressions></a>什么是正则表达式</h1>
一个正则表达式，就是用某种模式去匹配一类字符串的一个公式。很多人因为它们看上去比较古怪而且复杂所以不敢去使用——很不幸，这篇文章也不能够改变这一点，不过，经过一点点练习之后我就开始觉得这些复杂的表达式其实写起来还是相当简单的，而且，一旦你弄懂它们，你就能把数小时辛苦而且易错的文本处理工作压缩在几分钟（甚至几秒钟）内完成。正则表达式被各种文本编辑软件、类库（例如Rogue Wave的tools.h++）、脚本工具（像awk/grep/sed）广泛的支持，而且像Microsoft的Visual C++这种交互式IDE也开始支持它了。
<p>我们将在如下的章节中利用一些例子来解释正则表达式的用法，绝大部分的例子是基于<strong><tt>vi</tt></strong>中的文本替换命令和<strong><tt>grep</tt></strong>文件搜索命令来书写的，不过它们都是比较典型的例子，其中的概念可以在sed、awk、perl和其他支持正则表达式的编程语言中使用。你可以看看<a href="http://net.pku.edu.cn/~yhf/tao_regexps_zh.html#Regular_Expressions_In_Various_Tools"><u><font color=#800080>不同工具中的正则表达式</font></u></a>这一节，其中有一些在别的工具中使用正则表达式的例子。还有一个关于vi中文本替换命令（s）的<a href="http://net.pku.edu.cn/~yhf/tao_regexps_zh.html#ViSubstitutionCommandSyntax"><u><font color=#800080>简单说明</font></u></a>附在文后供参考。</p>
<h2>正则表达式基础</h2>
正则表达式由一些普通字符和一些<em>元字符（metacharacters）</em>组成。普通字符包括大小写的字母和数字，而元字符则具有特殊的含义，我们下面会给予解释。
<p>在最简单的情况下，一个正则表达式看上去就是一个普通的查找串。例如，正则表达式"testing"中没有包含任何元字符，，它可以匹配"testing"和"123testing"等字符串，但是不能匹配"Testing"。</p>
<p>要想真正的用好正则表达式，正确的理解元字符是最重要的事情。下表列出了所有的元字符和对它们的一个简短的描述。
<p>
<table cellSpacing=2 cellPadding=2>
    <tbody>
        <tr vAlign=baseline>
            <th align=left><strong><em>元字符</em></strong></th>
            <td>&nbsp;</td>
            <th align=left><strong><em>描述</em></strong></th>
        </tr>
        <tr>
            <td>
            <hr width="100%">
            </td>
            <td></td>
            <td>
            <hr width="100%">
            </td>
        </tr>
        <tr>
            <td vAlign=top align=middle>
            <center><strong><tt><font face="Courier New"><font size=+1>.</font></font></tt></strong> </center></td>
            <td></td>
            <td>匹配任何单个字符。例如正则表达式<strong><tt>r.t</tt></strong>匹配这些字符串：<em>rat</em>、<em>rut</em>、<em>r t</em>，但是不匹配<em>root</em>。&nbsp;</td>
        </tr>
        <tr>
            <td vAlign=top>
            <center><strong><tt><font face="Courier New"><font size=+1>$</font></font></tt></strong> </center></td>
            <td></td>
            <td>匹配行结束符。例如正则表达式<strong><tt>weasel$</tt></strong> 能够匹配字符串"<em>He's a weasel</em>"的末尾，但是不能匹配字符串"<em>They are a bunch of weasels.</em>"。&nbsp;</td>
        </tr>
        <tr>
            <td vAlign=top>
            <center><strong><font size=+1>^</font></strong> </center></td>
            <td></td>
            <td>匹配一行的开始。例如正则表达式<strong><tt>^When in</tt></strong>能够匹配字符串"<em>When in the course of human events</em>"的开始，但是不能匹配"<em>What and When in the"。</em></td>
        </tr>
        <tr>
            <td vAlign=top>
            <center><strong><tt><font face="Courier New"><font size=+1>*</font></font></tt></strong> </center></td>
            <td></td>
            <td>匹配0或多个正好在它之前的那个字符。例如正则表达式<strong><tt></tt></strong><strong><tt>.*</tt></strong>意味着能够匹配任意数量的任何字符。</td>
        </tr>
        <tr>
            <td vAlign=top>
            <center><strong><tt><font face="Courier New"><font size=+1>\</font></font></tt></strong> </center></td>
            <td></td>
            <td>这是引用府，用来将这里列出的这些元字符当作普通的字符来进行匹配。例如正则表达式<strong><tt>\$</tt></strong>被用来匹配美元符号，而不是行尾，类似的，正则表达式<tt><strong>\.</strong></tt>用来匹配点字符，而不是任何字符的通配符。</td>
        </tr>
        <tr>
            <td vAlign=top>
            <center><strong><tt><font face="Courier New"><font size=+1>[ ]&nbsp;</font></font></tt></strong> <br><strong><tt><font face="Courier New"><font size=+1>[c</font><font size=-1>1</font><font size=+1>-c</font><font size=-1>2</font><font size=+1>]</font></font></tt></strong> <br><strong><tt><font face="Courier New"><font size=+1>[^c</font><font size=-1>1</font><font size=+1>-c</font><font size=-1>2</font><font size=+1>]</font></font></tt></strong> </center></td>
            <td></td>
            <td>匹配括号中的任何一个字符。例如正则表达式<strong><tt>r[aou]t</tt></strong>匹配<em>rat</em>、<em>rot</em>和<em>rut</em>，但是不匹配<em>ret</em>。可以在括号中使用连字符-来指定字符的区间，例如正则表达式<strong><tt>[0-9]</tt></strong>可以匹配任何数字字符；还可以制定多个区间，例如正则表达式<strong><tt>[A-Za-z]</tt></strong>可以匹配任何大小写字母。另一个重要的用法是&#8220;排除&#8221;，要想匹配<em>除了</em>指定区间之外的字符——也就是所谓的补集——在左边的括号和第一个字符之间使用^字符，例如正则表达式<strong><tt>[^269A-Z]</tt></strong> 将匹配除了2、6、9和所有大写字母之外的任何字符。</td>
        </tr>
        <tr>
            <td vAlign=top>
            <center><strong><tt><font face="Courier New"><font size=+1>\&lt; \&gt;</font></font></tt></strong> </center></td>
            <td></td>
            <td>匹配词（<em>word</em>）的开始（\&lt;）和结束（\&gt;）。例如正则表达式<strong><tt><font face="Courier New">\&lt;the</font></tt></strong>能够匹配字符串"<em>for the wise</em>"中的"the"，但是不能匹配字符串"<em>otherwise</em>"中的"the"。<strong>注意</strong>：这个元字符不是所有的软件都支持的。</td>
        </tr>
        <tr>
            <td vAlign=top>
            <center><strong><tt><font face="Courier New"><font size=+1>\( \)</font></font></tt></strong> </center></td>
            <td></td>
            <td>将 \( 和 \) 之间的表达式定义为&#8220;组&#8221;（<em>group</em>），并且将匹配这个表达式的字符保存到一个临时区域（一个正则表达式中最多可以保存9个），它们可以用 <strong><tt>\1</tt></strong> 到<strong><tt>\9</tt></strong> 的符号来引用。</td>
        </tr>
        <tr>
            <td vAlign=baseline>
            <center><strong><tt><font face="Courier New"><font size=+1>|</font></font></tt></strong> </center></td>
            <td></td>
            <td>将两个匹配条件进行逻辑&#8220;或&#8221;（<em>Or</em>）运算。例如正则表达式<strong><tt><font face="Courier New">(him|her)</font></tt></strong> 匹配"<em>it belongs to him</em>"和"<em>it belongs to her</em>"，但是不能匹配"<em>it belongs to them.</em>"。<strong>注意</strong>：这个元字符不是所有的软件都支持的。</td>
        </tr>
        <tr vAlign=baseline>
            <td>
            <center><strong><tt><font face="Courier New"><font size=+1>+</font></font></tt></strong> </center></td>
            <td></td>
            <td>匹配1或多个正好在它之前的那个字符。例如正则表达式<strong><tt></tt></strong><strong><tt></tt></strong><strong><tt>9+</tt></strong>匹配9、99、999等。<strong>注意</strong>：这个元字符不是所有的软件都支持的。</td>
        </tr>
        <tr vAlign=baseline>
            <td>
            <center><strong><tt><font size=+1>?</font></tt></strong> </center></td>
            <td></td>
            <td>匹配0或1个正好在它之前的那个字符。<strong>注意</strong>：这个元字符不是所有的软件都支持的。</td>
        </tr>
        <tr vAlign=baseline>
            <td>
            <center><strong><font size=+1><tt><font face="Courier New">\{</font></tt><em>i</em><tt><font face="Courier New">\}</font></tt></font></strong> <br><strong><font size=+1><tt><font face="Courier New">\{</font></tt><em>i</em><tt><font face="Courier New">,</font></tt><em>j</em><tt><font face="Courier New">\}</font></tt></font></strong> </center></td>
            <td></td>
            <td vAlign=baseline>匹配指定数目的字符，这些字符是在它之前的表达式定义的。例如正则表达式<strong><tt><font face="Courier New">A[0-9]\{3\}</font></tt></strong> 能够匹配字符"A"后面跟着正好3个数字字符的串，例如A123、A348等，但是不匹配A1234。而正则表达式<strong><tt><font face="Courier New">[0-9]\{4,6\}</font></tt></strong> 匹配连续的任意4个、5个或者6个数字字符。<strong>注意</strong>：这个元字符不是所有的软件都支持的。</td>
        </tr>
    </tbody>
</table>
</p>
<p>&#160;</p>
<hr width="100%">
<p>最简单的元字符是点，它能够匹配任何单个字符（注意<strong>不</strong>包括新行符）。假定有个文件test.txt包含以下几行内容：</p>
<ul><tt>he is a rat</tt><br><tt>he is in a rut</tt><br><tt>the food is Rotten</tt><br><tt>I like root beer</tt> </ul>
    我们可以使用grep命令来测试我们的正则表达式，grep命令使用正则表达式去尝试匹配指定文件的每一行，并将至少有一处匹配表达式的所有行显示出来。命令
    <ul><tt>grep r.t test.txt</tt> </ul>
        在test.txt文件中的每一行中搜索正则表达式<strong><tt>r.t</tt></strong>，并打印输出匹配的行。正则表达式<strong><tt>r.t</tt></strong>匹配一个<strong><tt>r</tt></strong>接着任何一个字符再接着一个<strong><tt>t</tt></strong>。所以它将匹配文件中的<strong><tt>rat</tt></strong>和<strong><tt>rut</tt></strong>，而不能匹配<strong><tt>Rotten</tt></strong>中的<strong><tt>Rot</tt></strong>，因为正则表达式是大小写敏感的。要想同时匹配大写和小写字母，应该使用字符区间元字符（方括号）。正则表达式<strong><tt>[Rr]</tt></strong>能够同时匹配<strong><tt>R</tt></strong>和<strong><tt>r</tt></strong>。所以，要想匹配一个大写或者小写的<strong><tt>r</tt></strong>接着任何一个字符再接着一个<strong><tt>t</tt></strong>就要使用这个表达式：<strong><tt>[Rr].t</tt></strong>。
        <p>要想匹配行首的字符要使用抑扬字符（<em>^</em>）——又是也被叫做插入符。例如，想找到text.txt中行首"he"打头的行，你可能会先用简单表达式<strong><tt>he</tt></strong>，但是这会匹配第三行的<strong><tt>the</tt></strong>，所以要使用正则表达式<strong><tt>^he</tt></strong>，它只匹配在行首出现的<strong><tt>h</tt></strong>。 </p>
        <p>有时候指定&#8220;除了&#215;&#215;&#215;都匹配&#8221;会比较容易达到目的，当抑扬字符（<em>^</em>）出现在方括号中是，它表示&#8220;排除&#8221;，例如要匹配<strong><tt>he</tt></strong> ，但是排除前面是<strong><tt>t</tt></strong> or <strong><tt>s</tt></strong>的情性（也就是<strong><tt>the</tt></strong>和<strong><tt>s</tt></strong><strong><tt>he</tt></strong>），可以使用：<strong><tt>[^st]he</tt></strong>。 </p>
        <p>可以使用方括号来指定多个字符区间。例如正则表达式<strong><tt>[A-Za-z]</tt></strong>匹配任何字母，包括大写和小写的；正则表达式<strong><tt>[A-Za-z][A-Za-z]*</tt></strong> 匹配一个字母后面接着0或者多个字母（大写或者小写）。当然我们也可以用元字符<strong><tt>+</tt></strong>做到同样的事情，也就是：<strong><tt>[A-Za-z]+</tt></strong> ，和<strong><tt>[A-Za-z][A-Za-z]*</tt></strong>完全等价。但是要注意元字符<strong><tt>+</tt></strong> 并不是所有支持正则表达式的程序都支持的。关于这一点可以参考后面的<a href="http://net.pku.edu.cn/~yhf/tao_regexps_zh.html#Regular%20Expressions%20Syntax"><u><font color=#800080>正则表达式语法支持情况</font></u></a>。</p>
        <p>要指定特定数量的匹配，要使用大括号（注意必须使用反斜杠来转义）。想匹配所有<strong><tt>100</tt></strong>和<strong><tt>1000</tt></strong>的实例而排除<strong><tt>10</tt></strong>和<strong><tt>10000</tt></strong>，可以使用：<strong><tt>10\{2,3\}</tt></strong>，这个正则表达式匹配数字1后面跟着2或者3个0的模式。在这个元字符的使用中一个有用的变化是忽略第二个数字，例如正则表达式<strong><tt>0\{3,\}</tt></strong> 将匹配至少3个连续的0。</p>
        <h2><a name=SimpleCommands></a>简单的例子</h2>
        <p>这里有一些有代表性的、比较简单的例子。
        <p>
        <table cellSpacing=2 cellPadding=2>
            <tbody>
                <tr>
                    <td><strong><em>vi 命令</em></strong></td>
                    <td><strong><em>作用</em></strong></td>
                </tr>
                <tr>
                    <td>
                    <hr width="100%">
                    </td>
                    <td>
                    <hr width="100%">
                    </td>
                </tr>
                <tr>
                    <td><strong><tt><font face="Courier New"><font size=+1>:%s/ */ /g</font></font></tt></strong></td>
                    <td>把一个或者多个空格替换为一个空格。</td>
                </tr>
                <tr>
                    <td><strong><tt><font face="Courier New"><font size=+1>:%s/ *$//</font></font></tt></strong></td>
                    <td>去掉行尾的所有空格。</td>
                </tr>
                <tr>
                    <td><strong><tt><font face="Courier New"><font size=+1>:%s/^/ /</font></font></tt></strong></td>
                    <td>在每一行头上加入一个空格。</td>
                </tr>
                <tr>
                    <td><strong><tt><font face="Courier New"><font size=+1>:%s/^[0-9][0-9]* //</font></font></tt></strong></td>
                    <td>去掉行首的所有数字字符。</td>
                </tr>
                <tr>
                    <td><strong><tt><font face="Courier New"><font size=+1>:%s/b[aeio]g/bug/g</font></font></tt></strong></td>
                    <td>将所有的<em>bag</em>、<em>beg</em>、<em>big</em>和<em>bog</em>改为<em>bug</em>。&nbsp;</td>
                </tr>
                <tr>
                    <td><strong><tt><font face="Courier New"><font size=+1>:%s/t\([aou]\)g/h\1t/g</font></font></tt></strong></td>
                    <td>将所有<em>tag</em>、<em>tog</em>和<em>tug</em>分别改为<em>hat</em>、<em>hot</em>和<em>hug</em>（注意用group的用法和使用\1引用前面被匹配的字符）。</td>
                </tr>
                <tr>
                    <td></td>
                    <td></td>
                </tr>
            </tbody>
        </table>
        <h2><a name=MediumDifficultyExamples></a>中级的例子（神奇的咒语）</h2>
        <h3>例1</h3>
        <p>将所有方法foo(<em>a,b,c</em>)的实例改为foo(<em>b,a,c</em>)。这里a、b和c可以是任何提供给方法foo()的参数。也就是说我们要实现这样的转换：
        <p>
        <table cellSpacing=4 cellPadding=0>
            <tbody>
                <tr>
                    <td><strong>之前</strong></td>
                    <td>&nbsp;</td>
                    <td><strong>之后</strong></td>
                </tr>
                <tr>
                    <td><tt>foo(10,7,2)</tt></td>
                    <td></td>
                    <td><tt>foo(7,10,2)</tt></td>
                </tr>
                <tr>
                    <td><tt>foo(x+13,y-2,10)</tt></td>
                    <td></td>
                    <td><tt>foo(y-2,x+13,10)</tt></td>
                </tr>
                <tr>
                    <td><tt>foo( bar(8), x+y+z, 5)</tt></td>
                    <td></td>
                    <td><tt>foo( x+y+z, bar(8), 5)</tt></td>
                </tr>
            </tbody>
        </table>
        <p>下面这条替换命令能够实现这一魔法：</p>
        <ul><strong><tt><font face="Courier New">:%s/foo(\([^,]*\),\([^,]*\),\([^)]*\))/foo(\2,\1,\3)/g</font></tt></strong> </ul>
            <p>现在让我们把它打散来加以分析。写出这个表达式的基本思路是找出foo()和它的括号中的三个参数的位置。第一个参数是用这个表达式来识别的：：<strong><tt><font face="Courier New">\([^,]*\)</font></tt></strong>，我们可以从里向外来分析它：&nbsp;
            <p>
            <table>
                <tbody>
                    <tr>
                        <td><strong><tt><font face="Courier New">[^,]</font></tt></strong></td>
                        <td>&nbsp;</td>
                        <td>除了逗号之外的任何字符</td>
                    </tr>
                    <tr>
                        <td><strong><tt><font face="Courier New">[^,]*</font></tt></strong></td>
                        <td></td>
                        <td>0或者多个非逗号字符</td>
                    </tr>
                    <tr>
                        <td><strong><tt><font face="Courier New">\([^,]*\)</font></tt></strong></td>
                        <td></td>
                        <td>将这些非逗号字符标记为<strong><tt>\1</tt></strong>，这样可以在之后的替换模式表达式中引用它</td>
                    </tr>
                    <tr vAlign=baseline>
                        <td><strong><tt><font face="Courier New">\([^,]*\),</font></tt></strong></td>
                        <td></td>
                        <td>我们必须找到0或者多个非逗号字符后面跟着一个逗号，并且非逗号字符那部分要标记出来以备后用。</td>
                    </tr>
                </tbody>
            </table>
            <p>现在正是指出一个使用正则表达式常见错误的最佳时机。为什么我们要使用<strong><tt><font face="Courier New">[^,]*</font></tt></strong>这样的一个表达式，而不是更加简单直接的写法，例如：<strong><tt><font face="Courier New">.*</font></tt></strong>，来匹配第一个参数呢？设想我们使用模式<strong><tt><font face="Courier New">.*</font></tt></strong>来匹配字符串"10,7,2"，它应该匹配"10,"还是"10,7,"？为了解决这个两义性（ambiguity），正则表达式规定一律按照最长的串来，在上面的例子中就是"10,7,"，显然这样就找出了两个参数而不是我们期望的一个。所以，我们要使用<strong><tt><font face="Courier New">[^,]*</font></tt></strong>来强制取出第一个逗号之前的部分。</p>
            <p>这个表达式我们已经分析到了：<strong><tt><font face="Courier New">foo(\([^,]*\)</font></tt></strong>，这一段可以简单的翻译为&#8220;当你找到<strong><tt>foo(</tt></strong>就把其后直到第一个逗号之前的部分标记为<strong><tt><font face="Courier New">\1</font></tt></strong>&#8221;。然后我们使用同样的办法标记第二个参数为<strong><tt><font face="Courier New">\2</font></tt></strong>。对第三个参数的标记方法也是一样，只是我们要搜索所有的字符直到右括号。我们并没有必要去搜索第三个参数，因为我们不需要调整它的位置，但是这样的模式能够保证我们只去替换那些有三个参数的foo()方法调用，在foo()是一个重载（overoading）方法时这种明确的模式往往是比较保险的。然后，在替换部分，我们找到foo()的对应实例，然后利用标记好的部分进行替换，是的第一和第二个参数交换位置。</p>
            <h3>例2</h3>
            假设有一个CSV（comma separated value）文件，里面有一些我们需要的信息，但是格式却有问题，目前数据的列顺序是：姓名，公司名，州名缩写，邮政编码，现在我们希望讲这些数据重新组织，以便在我们的某个软件中使用，需要的格式为：姓名，州名缩写-邮政编码，公司名。也就是说，我们要调整列顺序，还要合并两个列来构成一个新列。另外，我们的软件不能接受逗号前后面有任何空格（包括空格和制表符）所以我们还必须要去掉逗号前后的所有空格。
            <p>这里有几行我们现在的数据：</p>
            <ul><tt>Bill Jones,&nbsp;&nbsp;&nbsp;&nbsp; HI-TEK Corporation ,&nbsp; CA, 95011</tt> <br><tt><font face="Courier New">Sharon Lee Smith,&nbsp; Design Works Incorporated,&nbsp; CA, 95012</font></tt> <br><tt><font face="Courier New">B. Amos&nbsp;&nbsp; ,&nbsp; Hill Street Cafe,&nbsp; CA, 95013</font></tt> <br><tt><font face="Courier New">Alexander Weatherworth,&nbsp; The Crafts Store,&nbsp; CA, 95014</font></tt> <br><tt><font face="Courier New">...</font></tt> </ul>
                我们希望把它变成这个样子：
                <ul><tt>Bill Jones,CA 95011,HI-TEK Corporation</tt> <br><tt><font face="Courier New">Sharon Lee Smith,CA 95012,Design Works Incorporated</font></tt> <br><tt><font face="Courier New">B. Amos,CA 95013,Hill Street Cafe</font></tt> <br><tt><font face="Courier New">Alexander Weatherworth,CA 95014,The Crafts Store</font></tt> <br><tt><font face="Courier New">...</font></tt> </ul>
                    我们将用两个正则表达式来解决这个问题。第一个移动列和合并列，第二个用来去掉空格。
                    <p>下面就是第一个替换命令：</p>
                    <ul><strong><tt><font face="Courier New">:%s/\([^,]*\),\([^,]*\),\([^,]*\),\(.*\)/\1,\3 \4,\2/</font></tt></strong> </ul>
                        这里的方法跟例1基本一样，第一个列（姓名）用这个表达式来匹配：<strong><tt><font face="Courier New">\([^,]*\)</font></tt></strong>，即第一个逗号之前的所有字符，而姓名内容被用<strong><tt><font face="Courier New">\1</font></tt></strong>标记下来。公司名和州名缩写字段用同样的方法标记为<strong><tt><font face="Courier New">\2</font></tt></strong>和<strong><tt><font face="Courier New">\3</font></tt></strong>，而最后一个字段用<strong><tt><font face="Courier New">\(.*\)</font></tt></strong>来匹配（"匹配所有字符直到行末"）。替换部分则引用上面标记的那些内容来进行构造。
                        <p>下面这个替换命令则用来去除空格：</p>
                        <ul><strong><tt><font face="Courier New">:%s/[ \t]*,[ \t]*/,/g</font></tt></strong> </ul>
                            我们还是分解来看：<strong><tt><font face="Courier New">[ \t]</font></tt></strong>匹配空格/制表符，<strong><tt><font face="Courier New">[ \t]*</font></tt></strong> 匹配0或多个空格/制表符，<strong><tt>[ \t]*</tt></strong>,匹配0或多个空格/制表符后面再加一个逗号，最后，<strong><tt><font face="Courier New">[ \t]*,[ \t]*</font></tt></strong>匹配0或多个空格/制表符接着一个逗号再接着0或多个空格/制表符。在替换部分，我们简单的我们找到的所有东西替换成一个逗号。这里我们使用了结尾的可选的<strong><tt>g</tt></strong>参数，这表示在每行中对所有匹配的串执行替换（而不是缺省的只替换第一个匹配串）。
                            <h3>例3</h3>
                            假设有一个多字符的片断重复出现，例如：
                            <blockquote><tt>Billy tried really hard</tt> <br><tt>Sally tried really really hard</tt> <br><tt>Timmy tried really really really hard</tt> <br><tt>Johnny tried really really really really hard</tt></blockquote>而你想把"really"、"really really"，以及任意数量连续出现的"really"字符串换成一个简单的"very"（simple is good!），那么以下命令：
                            <blockquote><strong><tt>:%s/\(really \)\(really \)*/very /</tt></strong></blockquote>就会把上述的文本变成：
                            <blockquote><tt>Billy tried very hard</tt> <br><tt>Sally tried very hard</tt> <br><tt>Timmy tried very hard</tt> <br><tt>Johnny tried very hard</tt></blockquote>表达式<strong><tt>\(really \)*</tt></strong>匹配0或多个连续的"really "（注意结尾有个空格），而<strong><tt>\(really \)\(really \)*</tt></strong> 匹配1个或多个连续的"really "实例。
                            <h2><a name=HardExamples></a>困难的例子（不可思议的象形文字）</h2>
                            <em>Coming soon</em>.
                            <p>&#160;</p>
                            <hr>
                            <h1><a name=Regular_Expressions_In_Various_Tools></a>不同工具中的正则表达式</h1>
                            OK，你已经准备使用RE（regular expressions，正则表达式），但是你并准备使用vi。所以，在这里我们给出一些在其他工具中使用RE的例子。另外，我还会总结一下你在不同程序之间使用RE可能发现的区别。
                            <p>当然，你也可以在Visual C++编辑器中使用RE。选择Edit-&gt;Replace，然后选择"Regular expression"选择框，Find What输入框对应上面介绍的vi命令<strong><tt>:%s/pat1/pat2/g</tt></strong>中的pat1部分，而Replace输入框对应pat2部分。但是，为了得到vi的执行范围和<strong><tt>g</tt></strong>选项，你要使用Replace All或者适当的手工Find Next and Replace（译者按：知道为啥有人骂微软弱智了吧，虽然VC中可以选中一个范围的文本，然后在其中执行替换，但是总之不够vi那么灵活和典雅）。</p>
                            <h2>sed</h2>
                            <p>Sed是<strong><u>S</u></strong>tream <strong><u>ED</u></strong>itor的缩写，是Unix下常用的基于文件和管道的编辑工具，可以在手册中得到关于sed的详细信息。 </p>
                            <p>这里是一些有趣的sed脚本，假定我们正在处理一个叫做price.txt的文件。注意这些编辑并不会改变源文件，sed只是处理源文件的每一行并把结果显示在标准输出中（当然很容易使用重定向来定制）：
                            <p>
                            <table>
                                <tbody>
                                    <tr>
                                        <td><strong><em>sed脚本</em></strong></td>
                                        <td>&nbsp;</td>
                                        <td><strong><em>描述</em></strong></td>
                                    </tr>
                                    <tr>
                                        <td>
                                        <hr width="100%">
                                        </td>
                                        <td></td>
                                        <td>
                                        <hr width="100%">
                                        </td>
                                    </tr>
                                    <tr vAlign=baseline>
                                        <td><strong><tt>sed 's/^$/d' price.txt</tt></strong></td>
                                        <td></td>
                                        <td>删除所有空行</td>
                                    </tr>
                                    <tr>
                                        <td><strong><tt>sed 's/^[ \t]*$/d' price.txt</tt></strong></td>
                                        <td></td>
                                        <td>删除所有只包含空格或者制表符的行</td>
                                    </tr>
                                    <tr>
                                        <td><strong><tt>sed 's/"//g' price.txt</tt></strong></td>
                                        <td></td>
                                        <td>删除所有引号</td>
                                    </tr>
                                </tbody>
                            </table>
                            </p>
                            <h2>awk</h2>
                            awk是一种编程语言，可以用来对文本数据进行复杂的分析和处理。可以在手册中得到关于awk的详细信息。这个古怪的名字是它作者们的姓的缩写（Aho，Weinberger和Kernighan）。
                            <p>在Aho，Weinberger和Kernighan的书<u>The AWK Programming Language</u>中有很多很好的awk的例子，请不要让下面这些微不足道的脚本例子限制你对awk强大能力的理解。我们同样假定我们针对price.txt文件进行处理，跟sed一样，awk也只是把结果显示在终端上。&nbsp;
                            <p>
                            <table>
                                <tbody>
                                    <tr>
                                        <td><strong><em>awk脚本</em></strong></td>
                                        <td>&nbsp;</td>
                                        <td><strong><em>描述</em></strong></td>
                                    </tr>
                                    <tr>
                                        <td>
                                        <hr width="100%">
                                        </td>
                                        <td></td>
                                        <td>
                                        <hr width="100%">
                                        </td>
                                    </tr>
                                    <tr vAlign=baseline>
                                        <td><strong><tt>awk '$0 !~ /^$/' price.txt</tt></strong></td>
                                        <td></td>
                                        <td>删除所有空行</td>
                                    </tr>
                                    <tr>
                                        <td><strong><tt>awk 'NF &gt; 0' price.txt</tt></strong></td>
                                        <td></td>
                                        <td>awk中一个更好的删除所有行的办法</td>
                                    </tr>
                                    <tr vAlign=baseline>
                                        <td><strong><tt>awk '$2 ~ /^[JT]/ {print $3}' price.txt</tt></strong></td>
                                        <td></td>
                                        <td>打印所有第二个字段是'J'或者'T'打头的行中的第三个字段</td>
                                    </tr>
                                    <tr vAlign=baseline>
                                        <td noWrap><strong><tt>awk '$2 !~ /[Mm]isc/ {print $3 + $4}' price.txt</tt></strong></td>
                                        <td></td>
                                        <td>针对所有第二个字段不包含'Misc'或者'misc'的行，打印第3和第4列的和（假定为数字）</td>
                                    </tr>
                                    <tr vAlign=baseline>
                                        <td><strong><tt>awk '$3 !~ /^[0-9]+\.[0-9]*$/ {print $0}' price.txt</tt></strong></td>
                                        <td></td>
                                        <td>打印所有第三个字段不是数字的行，这里数字是指<tt>d.d</tt>或者<tt>d这样的形式，其中</tt><tt>d</tt>是0到9的任何数字</td>
                                    </tr>
                                    <tr vAlign=baseline>
                                        <td><strong><tt>awk '$2 ~ /John|Fred/ {print $0}' price.txt</tt></strong></td>
                                        <td></td>
                                        <td>如果第二个字段包含'John'或者'Fred'则打印整行</td>
                                    </tr>
                                </tbody>
                            </table>
                            </p>
                            <h2>grep</h2>
                            grep是一个用来在一个或者多个文件或者输入流中使用RE进行查找的程序。它的name编程语言可以用来针对文件和管道进行处理。可以在手册中得到关于grep的完整信息。这个同样古怪的名字来源于vi的一个命令，<strong><tt>g/</tt></strong><em>re</em><strong><tt>/p</tt></strong>，意思是<strong>g</strong>lobal <strong>r</strong>egular <strong>e</strong>xpression <strong>p</strong>rint。
                            <p>下面的例子中我们假定在文件phone.txt中包含以下的文本，——其格式是姓加一个逗号，然后是名，然后是一个制表符，然后是电话号码：</p>
                            <ul>
                                <p><tt>Francis, John&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5-3871</tt> <br><tt>Wong, Fred&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4-4123</tt> <br><tt>Jones, Thomas&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1-4122</tt> <br><tt>Salazar, Richard&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5-2522</tt></p>
                            </ul>
                            <p>
                            <table>
                                <tbody>
                                    <tr>
                                        <td><strong><em>grep命令</em></strong></td>
                                        <td><strong><em>&nbsp;</em></strong></td>
                                        <td><strong><em>描述</em></strong></td>
                                    </tr>
                                    <tr>
                                        <td>
                                        <hr width="100%">
                                        </td>
                                        <td></td>
                                        <td>
                                        <hr width="100%">
                                        </td>
                                    </tr>
                                    <tr vAlign=baseline>
                                        <td><strong><tt>grep '\t5-...1' phone.txt</tt></strong></td>
                                        <td></td>
                                        <td>把所有电话号码以5开头以1结束的行打印出来，注意制表符是用<strong><tt>\t</tt></strong>表示的</td>
                                    </tr>
                                    <tr vAlign=baseline>
                                        <td noWrap><strong><tt>grep '^S[^ ]* R' phone.txt</tt></strong></td>
                                        <td></td>
                                        <td>打印所有姓以S打头和名以R打头的行</td>
                                    </tr>
                                    <tr vAlign=baseline>
                                        <td><strong><tt>grep '^[JW]' phone.txt</tt></strong></td>
                                        <td></td>
                                        <td>打印所有姓开头是J或者W的行</td>
                                    </tr>
                                    <tr vAlign=baseline>
                                        <td><strong><tt>grep ', ....\t' phone.txt</tt></strong></td>
                                        <td></td>
                                        <td>打印所有姓是4个字符的行，注意制表符是用<strong><tt>\t</tt></strong>表示的</td>
                                    </tr>
                                    <tr vAlign=baseline>
                                        <td><strong><tt>grep -v '^[JW]' phone.txt</tt></strong></td>
                                        <td></td>
                                        <td>打印所有不以J或者W开头的行</td>
                                    </tr>
                                    <tr vAlign=baseline>
                                        <td><strong><tt>grep '^[M-Z]' phone.txt</tt></strong></td>
                                        <td></td>
                                        <td>打印所有姓的开头是M到Z之间任一字符的行</td>
                                    </tr>
                                    <tr vAlign=baseline>
                                        <td><strong><tt>grep '^[M-Z].*[12]' phone.txt</tt></strong></td>
                                        <td></td>
                                        <td>打印所有姓的开头是M到Z之间任一字符，并且点号号码结尾是1或者2的行</td>
                                    </tr>
                                </tbody>
                            </table>
                            <h2>egrep</h2>
                            egrep是grep的一个扩展版本，它在它的正则表达式中支持更多的元字符。下面的例子中我们假定在文件phone.txt中包含以下的文本，——其格式是姓加一个逗号，然后是名，然后是一个制表符，然后是电话号码：
                            <ul><tt>Francis, John&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5-3871</tt> <br><tt>Wong, Fred&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4-4123</tt> <br><tt>Jones, Thomas&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1-4122</tt> <br><tt>Salazar, Richard&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5-2522</tt> </ul>
                                <p>
                                <table>
                                    <tbody>
                                        <tr>
                                            <td><strong><em>egrep command</em></strong></td>
                                            <td><strong><em>&nbsp;</em></strong></td>
                                            <td><strong><em>Description</em></strong></td>
                                        </tr>
                                        <tr>
                                            <td>
                                            <hr width="100%">
                                            </td>
                                            <td></td>
                                            <td>
                                            <hr width="100%">
                                            </td>
                                        </tr>
                                        <tr vAlign=baseline>
                                            <td><strong><tt>egrep '(John|Fred)' phone.txt</tt></strong></td>
                                            <td></td>
                                            <td>打印所有包含名字<em>John</em>或者<em>Fred</em>的行</td>
                                        </tr>
                                        <tr vAlign=baseline>
                                            <td noWrap><strong><tt>egrep 'John|22$|^W' phone.txt</tt></strong></td>
                                            <td></td>
                                            <td>打印所有包含<em>John</em> 或者以22结束或者以<em>W</em>的行</td>
                                        </tr>
                                        <tr>
                                            <td><strong><tt>egrep 'net(work)?s' report.txt</tt></strong></td>
                                            <td></td>
                                            <td>从report.txt中找到所有包含<em>networks</em>或者<em>nets</em>的行</td>
                                        </tr>
                                    </tbody>
                                </table>
                                <h2>
                                <hr width="100%">
                                </h2>
                                <h1><a name="Regular Expressions Syntax"></a>正则表达式语法支持情况</h1>
                                <table cellSpacing=0 border=1>
                                    <tbody>
                                        <tr>
                                            <td><strong>命令或环境</strong></td>
                                            <td><strong><tt><font face="Courier New">.</font></tt></strong></td>
                                            <td><strong><tt><font face="Courier New">[ ]</font></tt></strong></td>
                                            <td><strong><tt><font face="Courier New">^</font></tt></strong></td>
                                            <td><strong><tt><font face="Courier New">$</font></tt></strong></td>
                                            <td><strong><tt><font face="Courier New">\( \)</font></tt></strong></td>
                                            <td><strong><tt><font face="Courier New">\{ \}</font></tt></strong></td>
                                            <td><strong><tt><font face="Courier New">?</font></tt></strong></td>
                                            <td><strong><tt><font face="Courier New">+</font></tt></strong></td>
                                            <td><strong><tt><font face="Courier New">|</font></tt></strong></td>
                                            <td><strong><tt><font face="Courier New">( )</font></tt></strong></td>
                                        </tr>
                                        <tr>
                                            <td>vi</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;</td>
                                            <td>&nbsp;</td>
                                            <td>&nbsp;</td>
                                            <td>&nbsp;</td>
                                            <td>&nbsp;</td>
                                        </tr>
                                        <tr>
                                            <td>Visual C++</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;</td>
                                            <td>&nbsp;</td>
                                            <td>&nbsp;</td>
                                            <td>&nbsp;</td>
                                            <td>&nbsp;</td>
                                        </tr>
                                        <tr>
                                            <td>awk</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;</td>
                                            <td>&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                        </tr>
                                        <tr>
                                            <td>sed</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;</td>
                                            <td>&nbsp;</td>
                                            <td>&nbsp;</td>
                                            <td>&nbsp;</td>
                                        </tr>
                                        <tr>
                                            <td>Tcl</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                        </tr>
                                        <tr>
                                            <td>ex</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;</td>
                                            <td>&nbsp;</td>
                                            <td>&nbsp;</td>
                                            <td>&nbsp;</td>
                                        </tr>
                                        <tr>
                                            <td>grep</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;</td>
                                            <td>&nbsp;</td>
                                            <td>&nbsp;</td>
                                            <td>&nbsp;</td>
                                        </tr>
                                        <tr>
                                            <td>egrep</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                        </tr>
                                        <tr>
                                            <td>fgrep</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;X&nbsp;</td>
                                            <td>&nbsp;</td>
                                            <td>&nbsp;</td>
                                            <td>&nbsp;</td>
                                            <td>&nbsp;</td>
                                            <td>&nbsp;</td>
                                        </tr>
                                        <tr>
                                            <td>perl</td>
                                            <td>&nbsp;X</td>
                                            <td>&nbsp;X</td>
                                            <td>&nbsp;X</td>
                                            <td>&nbsp;X</td>
                                            <td>&nbsp;X</td>
                                            <td>&nbsp;</td>
                                            <td>&nbsp;X</td>
                                            <td>&nbsp;X</td>
                                            <td>&nbsp;X</td>
                                            <td>&nbsp;X</td>
                                        </tr>
                                    </tbody>
                                </table>
                                <p>&nbsp;</p>
                                <hr>
                                <h1><a name=ViSubstitutionCommandSyntax></a>vi替换命令简介</h1>
                                Vi的替换命令：
                                <ul><strong><tt>:</tt></strong><em>range</em><strong><tt>s/</tt></strong><em>pat1</em><strong><tt>/</tt></strong><em>pat2</em><strong><tt>/g</tt></strong> </ul>
                                    其中
                                    <ul><strong><tt>:</tt></strong> 这是Vi的命令执行界面。 </ul>
                                        <ul><em>range </em>是命令执行范围的指定，可以使用百分号（%）表示所有行，使用点（.）表示当前行，使用美元符号（$）表示最后一行。你还可以使用行号，例如<strong><tt>10,20</tt></strong>表示第10到20行，<strong><tt>.,$</tt></strong>表示当前行到最后一行，<strong><tt>.+2,$-5</tt></strong>表示当前行后两行直到全文的倒数第五行，等等。
                                            <p><strong><tt>s</tt></strong> 表示其后是一个替换命令。</p>
                                            <p><em>pat1 </em>这是要查找的一个正则表达式，这篇文章中有一大堆例子。</p>
                                        </ul>
                                        <ul><em>pat2 </em>这是希望把匹配串变成的模式的正则表达式，这篇文章中有一大堆例子。
                                            <p><strong><tt>g</tt></strong> 可选标志，带这个标志表示替换将针对行中每个匹配的串进行，否则则只替换行中第一个匹配串。</p>
                                        </ul>
<img src ="http://www.blogjava.net/yczz/aggbug/135350.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yczz/" target="_blank">飞鸟</a> 2007-08-08 21:14 <a href="http://www.blogjava.net/yczz/articles/135350.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java上传</title><link>http://www.blogjava.net/yczz/articles/57668.html</link><dc:creator>飞鸟</dc:creator><author>飞鸟</author><pubDate>Tue, 11 Jul 2006 08:25:00 GMT</pubDate><guid>http://www.blogjava.net/yczz/articles/57668.html</guid><wfw:comment>http://www.blogjava.net/yczz/comments/57668.html</wfw:comment><comments>http://www.blogjava.net/yczz/articles/57668.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yczz/comments/commentRss/57668.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yczz/services/trackbacks/57668.html</trackback:ping><description><![CDATA[这个Upload比smartUpload好用多了.完全是我一个个byte调试出来的,不象smartUpload的bug具多.<br />调用方法:<br />Upload up = new Upload();<br />up.init(request);<br />/**<br />此处可以调用setSaveDir(String saveDir);设置保存路径<br />调用setMaxFileSize(long size)设置上传文件的最大字节.<br />调用setTagFileName(String)设置上传后文件的名字(只对第一个文件有效)<br />*/<br />up. uploadFile();<br /><br />然后String[] names = up.getFileName();得到上传的文件名,文件绝对路径应该是<br />保存的目录saveDir+"/"+names[i];<br />可以通过up.getParameter("field");得到上传的文本或up.getParameterValues("filed")<br />得到同名字段如多个checkBox的值.<br />其它的自己试试.<br /><br />源码:____________________________________________________________<br />package com.inmsg.beans;<br /><br />import java.io.*;<br />import java.util.*;<br />import javax.servlet.*;<br />import javax.servlet.http.*;<br /><br />public class Upload {<br />  private String saveDir = "."; //要保存文件的路径<br />  private String contentType = ""; //文档类型<br />  private String charset = ""; //字符集<br />  private ArrayList tmpFileName = new ArrayList(); //临时存放文件名的数据结构<br />  private Hashtable parameter = new Hashtable(); //存放参数名和值的数据结构<br />  private ServletContext context; //程序上下文,用于初始化<br />  private HttpServletRequest request; //用于传入请求对象的实例<br />  private String boundary = ""; //内存数据的分隔符<br />  private int len = 0; //每次从内在中实际读到的字节长度<br />  private String queryString;<br />  private int count; //上载的文件总数<br />  private String[] fileName; //上载的文件名数组<br />  private long maxFileSize = 1024 * 1024 * 10; //最大文件上载字节;<br />  private String tagFileName = "";<br /><br />  public final void init(HttpServletRequest request) throws ServletException {<br />    this.request = request;<br />    boundary = request.getContentType().substring(30); //得到内存中数据分界符<br />    queryString = request.getQueryString();<br />  }<br /><br />  public String getParameter(String s) { //用于得到指定字段的参数值,重写request.getParameter(String s)<br />    if (parameter.isEmpty()) {<br />      return null;<br />    }<br />    return (String) parameter.get(s);<br />  }<br /><br />  public String[] getParameterValues(String s) { //用于得到指定同名字段的参数数组,重写request.getParameterValues(String s)<br />    ArrayList al = new ArrayList();<br />    if (parameter.isEmpty()) {<br />      return null;<br />    }<br />    Enumeration e = parameter.keys();<br />    while (e.hasMoreElements()) {<br />      String key = (String) e.nextElement();<br />      if ( -1 != key.indexOf(s + "||||||||||") || key.equals(s)) {<br />        al.add(parameter.get(key));<br />      }<br />    }<br />    if (al.size() == 0) {<br />      return null;<br />    }<br />    String[] value = new String[al.size()];<br />    for (int i = 0; i &lt; value.length; i++) {<br />      value[i] = (String) al.get(i);<br />    }<br />    return value;<br />  }<br /><br />  public String getQueryString() {<br />    return queryString;<br />  }<br /><br />  public int getCount() {<br />    return count;<br />  }<br /><br />  public String[] getFileName() {<br />    return fileName;<br />  }<br /><br />  public void setMaxFileSize(long size) {<br />    maxFileSize = size;<br />  }<br /><br />  public void setTagFileName(String filename) {<br />    tagFileName = filename;<br />  }<br /><br />  public void setSaveDir(String saveDir) { //设置上载文件要保存的路径<br />    this.saveDir = saveDir;<br />    File testdir = new File(saveDir); //为了保证目录存在,如果没有则新建该目录<br />    if (!testdir.exists()) {<br />      testdir.mkdirs();<br />    }<br />  }<br /><br />  public void setCharset(String charset) { //设置字符集<br />    this.charset = charset;<br />  }<br /><br />  public boolean uploadFile() throws ServletException, IOException { //用户调用的上载方法<br />    setCharset(request.getCharacterEncoding());<br />    return uploadFile(request.getInputStream());<br />  }<br /><br />  private boolean uploadFile(ServletInputStream servletinputstream) throws //取得央存数据的主方法<br />      ServletException, IOException {<br />    String line = null;<br />    byte[] buffer = new byte[256];<br />    while ( (line = readLine(buffer, servletinputstream, charset)) != null) {<br />      if (line.startsWith("Content-Disposition: form-data;")) {<br />        int i = line.indexOf("filename=");<br />        if (i &gt;= 0) { //如果一段分界符内的描述中有filename=,说明是文件的编码内容<br />          String fName = getFileName(line);<br />          if (fName.equals("")) {<br />            continue;<br />          }<br />          if (count == 0 &amp;&amp; tagFileName.length() != 0) {<br />            String ext = fName.substring( (fName.lastIndexOf(".") + 1));<br />            fName = tagFileName + "." + ext;<br />          }<br />          tmpFileName.add(fName);<br />          count++;<br />          while ( (line = readLine(buffer, servletinputstream, charset)) != null) {<br />            if (line.length() &lt;= 2) {<br />              break;<br />            }<br />          }<br />          File f = new File(saveDir, fName);<br />          FileOutputStream dos = new FileOutputStream(f);<br />          long size = 0l;<br />          while ( (line = readLine(buffer, servletinputstream, null)) != null) {<br />            if (line.indexOf(boundary) != -1) {<br />              break;<br />            }<br />            size += len;<br />            if (size &gt; maxFileSize) {<br />              throw new IOException("文件超过" + maxFileSize + "字节!");<br />            }<br />            dos.write(buffer, 0, len);<br />          }<br />          dos.close();<br />        }<br />        else { //否则是字段编码的内容<br />          String key = getKey(line);<br />          String value = "";<br />          while ( (line = readLine(buffer, servletinputstream, charset)) != null) {<br />            if (line.length() &lt;= 2) {<br />              break;<br />            }<br />          }<br />          while ( (line = readLine(buffer, servletinputstream, charset)) != null) {<br /><br />            if (line.indexOf(boundary) != -1) {<br />              break;<br />            }<br />            value += line;<br />          }<br />          put(key, value.trim(), parameter);<br />        }<br />      }<br />    }<br />    if (queryString != null) {<br />      String[] each = split(queryString, "&amp;");<br />      for (int k = 0; k &lt; each.length; k++) {<br />        String[] nv = split(each[k], "=");<br />        if (nv.length == 2) {<br />          put(nv[0], nv[1], parameter);<br />        }<br />      }<br />    }<br />    fileName = new String[tmpFileName.size()];<br />    for (int k = 0; k &lt; fileName.length; k++) {<br />      fileName[k] = (String) tmpFileName.get(k); //把ArrayList中临时文件名倒入数据中供用户调用<br />    }<br />    if (fileName.length == 0) {<br />      return false; //如果fileName数据为空说明没有上载任何文件<br />    }<br />    return true;<br />  }<br /><br />  private void put(String key, String value, Hashtable ht) {<br />    if (!ht.containsKey(key)) {<br />      ht.put(key, value);<br />    }<br />    else { //如果已经有了同名的KEY,就要把当前的key更名,同时要注意不能构成和KEY同名<br />      try {<br />        Thread.currentThread().sleep(1); //为了不在同一ms中产生两个相同的key<br />      }<br />      catch (Exception e) {}<br />      key += "||||||||||" + System.currentTimeMillis();<br />      ht.put(key, value);<br />    }<br />  }<br /><br />  /*<br />   调用ServletInputstream.readLine(byte[] b,int offset,length)方法,该方法是从ServletInputstream流中读一行<br />   到指定的byte数组,为了保证能够容纳一行,该byte[]b不应该小于256,重写的readLine中,调用了一个成员变量len为<br />   实际读到的字节数(有的行不满256),则在文件内容写入时应该从byte数组中写入这个len长度的字节而不是整个byte[]<br />   的长度,但重写的这个方法返回的是String以便分析实际内容,不能返回len,所以把len设为成员变量,在每次读操作时<br />   把实际长度赋给它.<br />   也就是说在处理到文件的内容时数据既要以String形式返回以便分析开始和结束标记,又要同时以byte[]的形式写到文件<br />   输出流中.<br />   */<br />  private String readLine(byte[] Linebyte,<br />                          ServletInputStream servletinputstream, String charset) {<br />    try {<br />      len = servletinputstream.readLine(Linebyte, 0, Linebyte.length);<br />      if (len == -1) {<br />        return null;<br />      }<br />      if (charset == null) {<br />        return new String(Linebyte, 0, len);<br />      }<br />      else {<br />        return new String(Linebyte, 0, len, charset);<br />      }<br /><br />    }<br />    catch (Exception _ex) {<br />      return null;<br />    }<br /><br />  }<br /><br />  private String getFileName(String line) { //从描述字符串中分离出文件名<br />    if (line == null) {<br />      return "";<br />    }<br />    int i = line.indexOf("filename=");<br />    line = line.substring(i + 9).trim();<br />    i = line.lastIndexOf("\\");<br />    if (i &lt; 0 || i &gt;= line.length() - 1) {<br />      i = line.lastIndexOf("/");<br />      if (line.equals("\"\"")) {<br />        return "";<br />      }<br />      if (i &lt; 0 || i &gt;= line.length() - 1) {<br />        return line;<br />      }<br />    }<br />    return line.substring(i + 1, line.length() - 1);<br />  }<br /><br />  private String getKey(String line) { //从描述字符串中分离出字段名<br />    if (line == null) {<br />      return "";<br />    }<br />    int i = line.indexOf("name=");<br />    line = line.substring(i + 5).trim();<br />    return line.substring(1, line.length() - 1);<br />  }<br /><br />  public static String[] split(String strOb, String mark) {<br />    if (strOb == null) {<br />      return null;<br />    }<br />    StringTokenizer st = new StringTokenizer(strOb, mark);<br />    ArrayList tmp = new ArrayList();<br />    while (st.hasMoreTokens()) {<br />      tmp.add(st.nextToken());<br />    }<br />    String[] strArr = new String[tmp.size()];<br />    for (int i = 0; i &lt; tmp.size(); i++) {<br />      strArr[i] = (String) tmp.get(i);<br />    }<br />    return strArr;<br />  }<br />}<br /><br /><br />下载其实非常简单，只要如下处理，就不会发生问题。<br /><br />  public void downLoad(String filePath,HttpServletResponse response,boolean isOnLine)<br />  throws Exception{<br />    File f = new File(filePath);<br />    if(!f.exists()){<br />      response.sendError(404,"File not found!");<br />      return;<br />    }<br />    BufferedInputStream br = new BufferedInputStream(new FileInputStream(f));<br />    byte[] buf = new byte[1024];<br />    int len = 0;<br />    <br />    response.reset();                                            //非常重要<br />    if(isOnLine){                                                //在线打开方式<br />      URL u = new URL("file:///"+filePath);<br />      response.setContentType(u.openConnection().getContentType());<br />      response.setHeader("Content-Disposition", "inline; filename="+f.getName());<br />                                                                 //文件名应该编码成UTF-8<br />    }<br />    else{                                                        //纯下载方式<br />      response.setContentType("application/x-msdownload"); <br />      response.setHeader("Content-Disposition", "attachment; filename=" + f.getName()); <br />    }<br />    OutputStream out = response.getOutputStream();<br />    while((len = br.read(buf)) &gt;0)<br />      out.write(buf,0,len);<br />    br.close();<br />    out.close();<br />  } <img src ="http://www.blogjava.net/yczz/aggbug/57668.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yczz/" target="_blank">飞鸟</a> 2006-07-11 16:25 <a href="http://www.blogjava.net/yczz/articles/57668.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JDBC对数据库的事务操作   </title><link>http://www.blogjava.net/yczz/articles/46812.html</link><dc:creator>飞鸟</dc:creator><author>飞鸟</author><pubDate>Thu, 18 May 2006 06:23:00 GMT</pubDate><guid>http://www.blogjava.net/yczz/articles/46812.html</guid><wfw:comment>http://www.blogjava.net/yczz/comments/46812.html</wfw:comment><comments>http://www.blogjava.net/yczz/articles/46812.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yczz/comments/commentRss/46812.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yczz/services/trackbacks/46812.html</trackback:ping><description><![CDATA[
		<table cellspacing="0" cellpadding="0" width="750" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span style="FONT-SIZE: 14px">
												<center> </center>
										</span>
								</td>
						</tr>
						<tr>
								<td>
								</td>
						</tr>
						<tr>
								<td align="middle">
										<table cellspacing="0" cellpadding="0" width="90%" border="0">
												<tbody>
														<tr>
																<td>
																		<span style="FONT-SIZE: 14px">
																				<br />JDBC对数据库的事务操作 
<p>                             
</p><p>1．  概述： 
</p><p>在jdbc的数据库操作中，一项事务是由一条或是多条表达式所组成的一个不可分割的工作单元。我们通过提交commit()或是回滚rollback（）来结束事务的操作。关于事务操作的方法都位于接口java.sql.Connection中。 
</p><p>2．  特点：<br />★ 在jdbc中，事务操作缺省是自动提交。也就是说，一条对数据库的更新表达式代表一项事务操作，操作成功后，系统将自动调用commit()来提交，否则将调用rollback()来回滚。<br />★ 在jdbc中，可以通过调用setAutoCommit(false)来禁止自动提交。之后就可以把多个数据库操作的表达式作为一个事务，在操作完成后调用commit()来进行整体提交，倘若其中一个表达式操作失败，都不会执行到commit()，并且将产生响应的异常；此时就可以在异常捕获时调用rollback()进行回滚。这样做可以保持多次更新操作后，相关数据的一致性，示例如下： 
</p><p>   try { 
</p><p>conn = 
</p><p>DriverManager.getConnection     
</p><p>("jdbc:oracle:thin:@host:1521:SID","username","userpwd"; 
</p><p>      conn.setAutoCommit(false);//禁止自动提交，设置回滚点 
</p><p>      stmt = conn.createStatement(); 
</p><p>stmt.executeUpdate(“alter table …”); //数据库更新操作1 
</p><p>stmt.executeUpdate(“insert into table …”); //数据库更新操作2 
</p><p>      conn.commit(); //事务提交 
</p><p>    }catch(Exception ex) {     
</p><p>        ex.printStackTrace(); 
</p><p>        try { 
</p><p>         conn.rollback(); //操作不成功则回滚 
</p><p>         }catch(Exception e) { 
</p><p>e.printStackTrace(); 
</p><p>          } 
</p><p>} 
</p><p></p><p>★      jdbc API支持事务对数据库的加锁，并且提供了5种操作支持，2种加锁密度。 
</p><p>５种支持： 
</p><p>static int TRANSACTION_NONE                = 0; 
</p><p>→禁止事务操作和加锁。 
</p><p>static  int TRANSACTION_READ_UNCOMMITTED    = 1; 
</p><p>→允许脏数据读写(dirty reads)、重复读写(repeatable reads)和影象读写（phntom 
</p><p>reads） 
</p><p>static  int TRANSACTION_READ_COMMITTED      = 2; 
</p><p>→禁止脏数据读写(dirty reads)，允许重复读写(repeatable reads)和影象读写（phntom reads） 
</p><p>static  int TRANSACTION_REPEATABLE_READ     = 4; 
</p><p>→禁止脏数据读写(dirty reads)和重复读写(repeatable reads)，允许影象读写（phntom reads） 
</p><p>static  int TRANSACTION_SERIALIZABLE        = 8; 
</p><p>→禁止脏数据读写(dirty reads)、重复读写(repeatable reads)和允许影象读写(phntom reads) 
</p><p>2种密度： 
</p><p>最后一项为表加锁，其余3～4项为行加锁。 
</p><p>     脏数据读写(dirty reads):当一个事务修改了某一数据行的值而未提交时，另一事务读取了此行值。倘若前一事务发生了回滚，则后一事务将得到一个无效的值（脏数据）。 
</p><p>     重复读写(repeatable reads):当一个事务在读取某一数据行时，另一事务同时在修改此数据行。则前一事务在重复读取此行时将得到一个不一致的值。 
</p><p>     影象读写(phantomreads):当一个事务在某一表中进行数据查询时，另一事务恰好插入了满足了查询条件的数据行。则前一事务在重复读取满足条件的值时，将得到一个额外的“影象“值。 
</p><p>    Jdbc根据数据库提供的缺省值来设置事务支持及其加锁，当然，也可以手工设置： 
</p><p>   setTransactionIsolation（TRANSACTION_READ_UNCOMMITTED）; 
</p><p>可以查看数据库的当前设置： 
</p><p>   getTransactionIsolation() 
</p><p>需要注意的是，在进行受动设置时，数据库及其驱动程序必须得支持相应的事务操作操作才行。 
</p><p>      上述设置随着值的增加，其事务的独立性增加，更能有效的防止事务操作之间的冲突；同时也增加了加锁的开销，降低了用户之间访问数据库的并发性，程序的运行效率也回随之降低。因此得平衡程序运行效率和数据一致性之间的冲突。一般来说，对于只涉及到数据库的查询操作时，可以采用TRANSACTION_READ_UNCOMMITTED方式；对于数据查询远多于更新的操作，可以采用TRANSACTION_READ_COMMITTED方式；对于更新操作较多的，可以采用TRANSACTION_REPEATABLE_READ；在数据一致性要求更高的场合再考虑最后一项，由于涉及到表加锁，因此会对程序运行效率产生较大的影响。 
</p><p>另外，在oracle中数据库驱动对事务处理的缺省值是TRANSACTION_NONE，即不支持事务操作，所以需要在程序中手动进行设置。 
</p><p>3．  小结 
</p><p>jdbc提供的对数据库事务操作的支持是比较完整的，通过事务操作可以提高程序的运行效率，保持数据的一致性<br /></p></span>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/yczz/aggbug/46812.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yczz/" target="_blank">飞鸟</a> 2006-05-18 14:23 <a href="http://www.blogjava.net/yczz/articles/46812.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jakarta dbcp在应用程序中使用的例子</title><link>http://www.blogjava.net/yczz/articles/46802.html</link><dc:creator>飞鸟</dc:creator><author>飞鸟</author><pubDate>Thu, 18 May 2006 06:06:00 GMT</pubDate><guid>http://www.blogjava.net/yczz/articles/46802.html</guid><wfw:comment>http://www.blogjava.net/yczz/comments/46802.html</wfw:comment><comments>http://www.blogjava.net/yczz/articles/46802.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yczz/comments/commentRss/46802.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yczz/services/trackbacks/46802.html</trackback:ping><description><![CDATA[
		<p>/*<br /> * Copyright 1999-2004 The Apache Software Foundation.<br /> * <br /> * Licensed under the Apache License, Version 2.0 (the "License");<br /> * you may not use this file except in compliance with the License.<br /> * You may obtain a copy of the License at<br /> * <br /> *      <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a><br /> * <br /> * Unless required by applicable law or agreed to in writing, software<br /> * distributed under the License is distributed on an "AS IS" BASIS,<br /> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<br /> * See the License for the specific language governing permissions and<br /> * limitations under the License.<br /> */</p>
		<p>import javax.sql.DataSource;<br />import java.sql.Connection;<br />import java.sql.Statement;<br />import java.sql.ResultSet;<br />import java.sql.SQLException;</p>
		<p>//<br />// Here are the dbcp-specific classes.<br />// Note that they are only used in the setupDataSource<br />// method. In normal use, your classes interact<br />// only with the standard JDBC API<br />//<br />import org.apache.commons.dbcp.BasicDataSource;</p>
		<p>//<br />// Here's a simple example of how to use the BasicDataSource.<br />// In this example, we'll construct the BasicDataSource manually,<br />// but you could also configure it using an external conifguration file.<br />//</p>
		<p>//<br />// Note that this example is very similiar to the PoolingDriver<br />// example.</p>
		<p>//<br />// To compile this example, you'll want:<br />//  * commons-pool.jar<br />//  * commons-dbcp.jar<br />//  * j2ee.jar (for the javax.sql classes)<br />// in your classpath.<br />//<br />// To run this example, you'll want:<br />//  * commons-collections.jar<br />//  * commons-pool.jar<br />//  * commons-dbcp.jar<br />//  * j2ee.jar (for the javax.sql classes)<br />//  * the classes for your (underlying) JDBC driver<br />// in your classpath.<br />//<br />// Invoke the class using two arguments:<br />//  * the connect string for your underlying JDBC driver<br />//  * the query you'd like to execute<br />// You'll also want to ensure your underlying JDBC driver<br />// is registered.  You can use the "jdbc.drivers"<br />// property to do this.<br />//<br />// For example:<br />//  java -Djdbc.drivers=oracle.jdbc.driver.OracleDriver \<br />//       -classpath commons-collections.jar:commons-pool.jar:commons-dbcp.jar:j2ee.jar:oracle-jdbc.jar:. \<br />//       ManualPoolingDataSourceExample<br />//       "jdbc:oracle:thin:scott/tiger@myhost:1521:mysid"<br />//       "SELECT * FROM DUAL"<br />//<br />public class BasicDataSourceExample {</p>
		<p>    public static void main(String[] args) {<br />        // First we set up the BasicDataSource.<br />        // Normally this would be handled auto-magically by<br />        // an external configuration, but in this example we'll<br />        // do it manually.<br />        //<br />        System.out.println("Setting up data source.");<br />        DataSource dataSource = setupDataSource(args[0]);<br />        System.out.println("Done.");</p>
		<p>        //<br />        // Now, we can use JDBC DataSource as we normally would.<br />        //<br />        Connection conn = null;<br />        Statement stmt = null;<br />        ResultSet rset = null;</p>
		<p>        try {<br />            System.out.println("Creating connection.");<br />            conn = dataSource.getConnection();<br />            System.out.println("Creating statement.");<br />            stmt = conn.createStatement();<br />            System.out.println("Executing statement.");<br />            rset = stmt.executeQuery(args[1]);<br />            System.out.println("Results:");<br />            int numcols = rset.getMetaData().getColumnCount();<br />            while(rset.next()) {<br />                for(int i=1;i&lt;=numcols;i++) {<br />                    System.out.print("\t" + rset.getString(i));<br />                }<br />                System.out.println("");<br />            }<br />        } catch(SQLException e) {<br />            e.printStackTrace();<br />        } finally {<br />            try { rset.close(); } catch(Exception e) { }<br />            try { stmt.close(); } catch(Exception e) { }<br />            try { conn.close(); } catch(Exception e) { }<br />        }<br />    }</p>
		<p>    public static DataSource setupDataSource(String connectURI) {<br />        BasicDataSource ds = new BasicDataSource();<br />        ds.setDriverClassName("oracle.jdbc.driver.OracleDriver");<br />        ds.setUsername("scott");<br />        ds.setPassword("tiger");<br />        ds.setUrl(connectURI);<br />        return ds;<br />    }</p>
		<p>    public static void printDataSourceStats(DataSource ds) throws SQLException {<br />        BasicDataSource bds = (BasicDataSource) ds;<br />        System.out.println("NumActive: " + bds.getNumActive());<br />        System.out.println("NumIdle: " + bds.getNumIdle());<br />    }</p>
		<p>    public static void shutdownDataSource(DataSource ds) throws SQLException {<br />        BasicDataSource bds = (BasicDataSource) ds;<br />        bds.close();<br />    }<br />}<br /></p>
<img src ="http://www.blogjava.net/yczz/aggbug/46802.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yczz/" target="_blank">飞鸟</a> 2006-05-18 14:06 <a href="http://www.blogjava.net/yczz/articles/46802.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Swt常用控件中文教程</title><link>http://www.blogjava.net/yczz/articles/42424.html</link><dc:creator>飞鸟</dc:creator><author>飞鸟</author><pubDate>Fri, 21 Apr 2006 17:23:00 GMT</pubDate><guid>http://www.blogjava.net/yczz/articles/42424.html</guid><wfw:comment>http://www.blogjava.net/yczz/comments/42424.html</wfw:comment><comments>http://www.blogjava.net/yczz/articles/42424.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yczz/comments/commentRss/42424.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yczz/services/trackbacks/42424.html</trackback:ping><description><![CDATA[1、Eclipse中swt的配置
<p>　　建议配置：jdk1.4.2以及eclipse3.1</p><p>　　在代码中调用swt控件之前，首先建立一个项目，然后选择该项目的properties -&gt; Java Build Path，将standard Widget ToolKit加入到Library页当中。</p><p>　　接下来可以建立第一个eclipse小程序，新建一个class，并且在该class所对应的代码中输入如下程序，其中package以及class名称根据实际情况来确定名称。</p><p>package mypakage;<br />import org.eclipse.swt.widgets.*;<br />import org.eclipse.swt.*;<br />/*导入需要的类库*/<br />public class Myfrm1 {<br />public Myfrm1() {<br />super();<br />}<br />public static void main(String[] args) {<br />Display display = new Display();<br />Shell shell = new Shell(display);<br />/*shell为一个窗口对象*/<br />Label label = new Label(shell, SWT.NONE);<br />label.setText("Hello, World!"); /*创建一个标签对象并且设置标题文字*/<br />label.pack();<br />shell.pack();<br />shell.open(); /*打开并显示窗口*/</p><p>while(!shell.isDisposed())<br />if(!display.readAndDispatch())<br />display.sleep(); /*在窗口没有销毁之前，显示对象一直处于等待状态*/</p><p>display.dispose(); /*否则，销毁对象，释放对象所占据的资源*/<br />label.dispose();<br />}<br />}</p><p>　　运行上述代码（run -&gt; debug -&gt; swt application）将产生如下所示的一个窗口</p><p>　　2、button的使用</p><p>　　按钮可能的类型有很多，例如：</p><p>SWT.BORDER 含有边框的按钮</p><p>SWT.CHECK 复选按钮</p><p>SWT.PUSH 普通按钮</p><p>SWT.RADIO 单选按钮</p><p>　　3、Text的使用</p><p>　　文本框的类型也有很多种选择，例如：</p><p>SWT.BORDER 含有边框</p><p>SWT.READ_ONLY 只读</p><p>　　下图为包含按钮以及文本框的窗口</p><p>　　设计上述窗口所对应的代码为：</p><p>package mypakage;<br />import org.eclipse.swt.widgets.*;<br />import org.eclipse.swt.SWT;<br />import org.eclipse.swt.events.*;<br />import org.eclipse.swt.layout.*;<br />public class Myfrm1 {<br />public Myfrm1() {<br />super();<br />}<br />public static void main(String[] args) {<br />Display display = new Display( );<br />Shell shell = new Shell(display);<br />shell.setSize(300, 200);<br />shell.setLayout(new RowLayout( ));<br />shell.setText("Button Example");<br />final Button button = new Button(shell, SWT.BORDER);<br />button.setText("Click Me");<br />final Text text = new Text(shell, SWT.BORDER);<br />shell.open( );</p><p>while(!shell.isDisposed( )) {<br />if(!display.readAndDispatch( )) display.sleep( );<br />}<br />display.dispose( );<br />}<br />}</p><p>　　如果想对控件的位置以及大小进行精确的设置，可以使用setBounds(x, y, width, height)方法来取代shell.setLayout(new RowLayout( ))。例如：button.setBounds(80, 80, 90, 20);</p><p>　　button的监听及事件处理</p><p>　　对按钮单击事件处理的代码：</p><p>button.addSelectionListener(new SelectionListener( )<br />{<br />public void widgetSelected(SelectionEvent event)<br />{<br />text.setText("No worries!");<br />}<br />public void widgetDefaultSelected(SelectionEvent event)</p><p>{<br />text.setText("No worries!");<br />}<br />});</p><p>　　将以上代码加入到shell.open之前，当点击按钮时产生以下效果：</p><p><br />　　分析：由于为button按钮增加了一个监听器，按钮时刻处于被“监控”的状态，当按钮控件被选择（点击）既选择事件发生时，对文本控件进行赋值”No worries”。</p><p>　　根据监听事件的原理，设计如下程序，该程序能够获得鼠标的X坐标，显示在文本框中：</p><p>package mypakage;<br />import org.eclipse.swt.widgets.*;<br />import org.eclipse.swt.SWT;<br />import org.eclipse.swt.events.*;<br />import org.eclipse.swt.layout.*;</p><p>public class Myfrm1 {<br />public Myfrm1() {<br />super();<br />}<br />public static void main(String[] args) {<br />Display display = new Display( );<br />Shell shell = new Shell(display);<br />shell.setSize(300, 200);<br />shell.setLayout(new RowLayout( ));<br />final Text text = new Text(shell, SWT.SHADOW_IN);</p><p>shell.addMouseMoveListener(new MouseMoveListener( )<br />{<br />public void mouseMove(MouseEvent e)<br />{<br />Integer y=new Integer(e.x); /*将x坐标转换为Integer类型的对象*/<br />text.setText(y.toString());<br />}<br />});</p><p>shell.open( );<br />while(!shell.isDisposed( )) {<br />if(!display.readAndDispatch( )) display.sleep( );<br />}<br />display.dispose( );<br />}<br />}</p><p>　　监听方式：</p><p>ControlListener 用于处理移动以及尺寸变化</p><p>FocusListener 用于处理得到焦点以及失去焦点</p><p>KeyListener 处理按键的输入</p><p>MouseListener , MouseMoveListener, MouseTrackListener 对鼠标的动作进行处理</p><p>SelectionListener 处理控件的选择行为（包括按钮的点击）</p><p>　　注意：监听方式与其所能够处理的事件具有一定的关联性，既监听方式决定了所能够处理事件的种类，例如：</p><p>shell.addMouseListener(new MouseListener( )<br />{<br />public void mouseMove(MouseEvent e)<br />{text.setText("mousemove");}<br />public void mouseDoubleClick(MouseEvent e)<br />{text.setText("mousedbclc");}<br />public void mouseDown(MouseEvent e)<br />{}<br />public void mouseUp(MouseEvent e)<br />{}<br />});</p><p>　　你会发现在鼠标移动时，text.setText("mousemove");始终不能够执行；并且mouseDown、mouseUp事件不能够省略，原因就在于MouseListener只能处理mouseDoubleClick、mouseDown、mouseUp三类事件，而且这三类事件不能够分离。</p><p>　　3、List控件</p><p>　　List控件的样式包括：</p><p>SWT.BORDER 含有边框</p><p>SWT.H_SCROLL 含有水平滚动条</p><p>SWT.V_SCROLL 含有垂直滚动条</p><p>SWT.SINGLE 允许单选</p><p>SWT.MULTI 允许复选</p><p>　　若要创建一个含有从11个元素的List，可以通过以下代码来实现</p><p>final List list = new List (shell, SWT.SINGLE);<br />for (int i=0;i&lt;=10;i++)<br />list.add("item"+i);</p><p>　　以下实例能够判断List控件中所选择的选项，并且输出显示在控制台中：</p><p>package mypakage;<br />import org.eclipse.swt.widgets.*;<br />import org.eclipse.swt.SWT;<br />import org.eclipse.swt.events.*;<br />import org.eclipse.swt.layout.*;<br />public class Myfrm1 {<br />public Myfrm1() {<br />super();<br />}<br />public static void main(String[] args) {<br />Display display = new Display ( );<br />Shell shell = new Shell (display);<br />shell.setText("List Example");<br />shell.setSize(300, 200);<br />shell.setLayout(new FillLayout(SWT.VERTICAL));<br />final List list = new List (shell, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL);<br />for (int loopIndex = 0; loopIndex &lt; 100; loopIndex++){<br />list.add("Item " + loopIndex);<br />}<br />list.addSelectionListener(new SelectionListener( )<br />{<br />public void widgetSelected(SelectionEvent event)<br />{<br />int selections[] = list.getSelectionIndices ( );<br />String outText = "";<br />for (int loopIndex = 0; loopIndex &lt; selections.length;<br />loopIndex++) outText += selections[loopIndex] + " ";<br />System.out.println ("You selected: " + outText);<br />}<br />public void widgetDefaultSelected(SelectionEvent event)<br />{<br />int [] selections = list.getSelectionIndices ( );<br />String outText = "";<br />for (int loopIndex = 0; loopIndex &lt; selections.length; loopIndex++)<br />outText += selections[loopIndex] + " ";<br />System.out.println ("You selected: " + outText);<br />}<br />});<br />shell.open ( );<br />while (!shell.isDisposed ( )) {<br />if (!display.readAndDispatch ( )) display.sleep ( );<br />}<br />display.dispose ( );<br />}<br />}</p><p>　　效果图：</p><p>　　You selected: 4 5 6 7 8 9 10</p><p>　　分析：list.getSelectionIndices ( )方法将会获得被选择项目的集合， selections[]或者[] elections表示动态一维数组。</p><p>　　4、Menu控件</p><p>　　建立菜单的一般步骤为：</p><p>　　1、在建立菜单时，首先需要建立一个菜单栏，需要使用SWT.BAR属性</p><p>　　Menu menuBar = new Menu(shell, SWT.BAR);</p><p>　　2、在菜单栏的基础之上，创建下拉菜单的所对应的顶级菜单项，需要使用SWT.CASCADE属性<br />fileMenuHeader = new MenuItem(menuBar, SWT.CASCADE);</p><p>　　fileMenuHeader.setText("&amp;File");</p><p>　　3、建立与顶级菜单项相关的下拉式菜单</p><p>　　dropMenu1 = new Menu(shell, SWT.DROP_DOWN);</p><p>　　4、将顶级菜单项与下拉菜单关联</p><p>MenuHeader1.setMenu(dropMenu1);</p><p>　　5、为下拉菜单添加子菜单项</p><p>dropitem1= new MenuItem(dropMenu1, SWT.PUSH);<br />dropitem1.setText("open");<br />…<br />…</p><p>　　6、最后，在窗口中指定需要显示的菜单栏</p><p>shell.setMenuBar(menuBar);</p><p>　　菜单的监听及事件</p><p>　　参照按钮的监听以及事件，设计如下程序，当点击 File子菜单下的“open”时，在文本框中显示“click open menu!”</p><p>dropitem1.addSelectionListener(new SelectionListener()<br />{<br />public void widgetSelected(SelectionEvent event)<br />{<br />text.setText("click open menu!");<br />}<br />public void widgetDefaultSelected(SelectionEvent event)<br />{<br />text.setText("click open menu!");<br />}<br />});</p><p>　　5、使用工具栏toobar</p><p>　　建立工具栏可以通过如下方式：ToolBar toolbar = new ToolBar(shell, SWT.NONE);</p><p>　　在工具栏的基础之上创建工具栏子按钮，并且设置子按钮的标题：</p><p>ToolItem item1 = new ToolItem(toolbar, SWT.PUSH);<br />item1.setText("item1");</p><p>　　例如：</p><p>ToolBar toolbar = new ToolBar(shell, SWT.NONE);<br />ToolItem item1 = new ToolItem(toolbar, SWT.PUSH);<br />item1.setText("item1");<br />ToolItem item2 = new ToolItem(toolbar, SWT.PUSH);<br />item2.setText("item2");</p><p>　　工具栏的监听及事件</p><p>　　实例：创建一个监听对象，将该监听对象应用于每一个按钮，最终来判断鼠标点击的是哪一个按钮，效果图如下。</p><p>Listener listener = new Listener( ) {<br />public void handleEvent(Event event) {<br />ToolItem item =(ToolItem)event.widget;<br />String string = item.getText( );<br />text.setText("You selected:" + string); }<br />};<br />item1.addListener(SWT.Selection, listener);<br />item2.addListener(SWT.Selection, listener);<br />item3.addListener(SWT.Selection, listener);<br />item4.addListener(SWT.Selection, listener);</p><p>　　6、滚动条slider的使用</p><p>　　滚动条分为有边框、垂直、水平三种类型，利用slider.setBounds方法可以指定滚动条所在的位置。</p><p>　　滚动条所能够处理事件的包括：</p><p>SWT.ARROW_DOWN 向下或向右按钮被点击</p><p>SWT.ARROW_UP 向左或向上按钮被点击</p><p>SWT.DRAG 滑块按钮被托动</p><p>SWT.END 滑块到达终点</p><p>SWT.HOME 滑块到达起点</p><p>SWT.PAGE_DOWN 下方或右侧的滚动条被点击</p><p>SWT.PAGE_UP 上方或左侧的滚动条被点击</p><p>　　实例：根据滑块的位置移动按钮位置</p><p>slider.addListener(SWT.Selection, new Listener( ) {</p><p>public void handleEvent(Event event) {</p><p>switch(event.detail) {</p><p>case SWT.ARROW_DOWN: button.setBounds(slider.getSelection(),0,20,10);</p><p>break;</p><p>case SWT.ARROW_UP:button.setBounds(slider.getSelection(),0,20,10);</p><p>break;</p><p>case SWT.DRAG:button.setBounds(slider.getSelection(),0,20,10);</p><p>break;</p><p>case SWT.END:button.setBounds(slider.getSelection(),0,20,10);</p><p>break;</p><p>case SWT.HOME:button.setBounds(slider.getSelection(),0,20,10);</p><p>break;</p><p>case SWT.PAGE_DOWN:button.setBounds(slider.getSelection(),0,20,10);</p><p>break;</p><p>case SWT.PAGE_UP:button.setBounds(slider.getSelection(),0,20,10);</p><p>break;</p><p>}<br />}</p><p>});</p><p>　　7、树形控件Tree</p><p>　　树形控件使用的方法为，首先创建一个Tree类型的对象，其次在该对象的基础之上继续扩展节点，以及扩展节点的子节点。</p><p>　　final Tree tree = new Tree(shell, SWT.BORDER);</p><p>　　可以利用tree.setSize方法来改变树形控件的大小。在创建节点时，需要指明该节点所依赖的父节点的名称，如TreeItem item0 = new TreeItem(tree, 0);，那么item0将成为tree对象中的0级（顶级）节点。</p><p>　　如下程序将在tree对象的基础之上产生9个节点：</p><p>final Tree tree = new Tree(shell, SWT.BORDER);</p><p>tree.setSize(290, 290);</p><p>for(int loopIndex1 = 2000; loopIndex1 &lt;= 2008; loopIndex1++) {</p><p>TreeItem item0 = new TreeItem(tree, 0);</p><p>item0.setText("Year " + loopIndex1);</p><p>}</p><p>　　在上述实例的基础上为每一个0级节点的基础上扩展出12个节点：</p><p>for(int loopIndex1 = 2000; loopIndex1 &lt;= 2008; loopIndex1++) {</p><p>TreeItem item0 = new TreeItem(tree, 0);</p><p>item0.setText("Year " + loopIndex1);</p><p>for(int loopIndex2 = 1; loopIndex2 &lt;= 12; loopIndex2++) {</p><p>TreeItem item1 = new TreeItem(item0, 0);</p><p>item1.setText("Month " + loopIndex2);<br />}</p><p>}</p><p>　　8、对话框dialog</p><p>　　对话框是一个依托于主窗体的子窗体，如图所示。</p><p>　　例如：当在主窗体中点击按钮时，弹出一个对话框dialog，当关闭对话框时按钮显示“dialog is disposed”</p><p>Display display = new Display( );</p><p>final Shell shell = new Shell(display);</p><p>shell.setSize(300, 200);</p><p>shell.setText("main");</p><p>final Button opener = new Button(shell, SWT.PUSH);</p><p>opener.setText("Click Me");</p><p>opener.setBounds(20, 20, 50, 25);</p><p>final Shell dialog = new Shell(shell, SWT.APPLICATION_MODAL |</p><p>SWT.DIALOG_TRIM);</p><p>dialog.setText("dialog");</p><p>dialog.setBounds(10,10,50,60);</p><p>dialog.addDisposeListener(new DisposeListener(){</p><p>public void widgetDisposed(DisposeEvent e){</p><p>opener.setText("dialog is disposed");</p><p>}<br />});</p><p>Listener openerListener = new Listener( ) {</p><p>public void handleEvent(Event event) {</p><p>dialog.open( );</p><p>}</p><p>};</p><p>opener.addListener(SWT.Selection, openerListener);</p><p>shell.open( );</p><p>while(!dialog.isDisposed( )) {</p><p>if(!display.readAndDispatch( )) display.sleep( );</p><p>}</p><p>while (!shell.isDisposed( )) {</p><p>if (!display.readAndDispatch( ))</p><p>display.sleep( );</p><p>}</p><p>display.dispose( );</p><!-- end 主体内容 --><img src ="http://www.blogjava.net/yczz/aggbug/42424.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yczz/" target="_blank">飞鸟</a> 2006-04-22 01:23 <a href="http://www.blogjava.net/yczz/articles/42424.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>