﻿<?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-自然-文章分类-Struts</title><link>http://www.blogjava.net/masen/category/20993.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 20 Aug 2007 18:26:12 GMT</lastBuildDate><pubDate>Mon, 20 Aug 2007 18:26:12 GMT</pubDate><ttl>60</ttl><item><title>javascript正则表达式对象</title><link>http://www.blogjava.net/masen/articles/138106.html</link><dc:creator>Masen</dc:creator><author>Masen</author><pubDate>Mon, 20 Aug 2007 05:20:00 GMT</pubDate><guid>http://www.blogjava.net/masen/articles/138106.html</guid><wfw:comment>http://www.blogjava.net/masen/comments/138106.html</wfw:comment><comments>http://www.blogjava.net/masen/articles/138106.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/masen/comments/commentRss/138106.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/masen/services/trackbacks/138106.html</trackback:ping><description><![CDATA[<p><br>本对象包含正则表达式模式以及表明如何应用模式的标志。<br>语法 1 re = /pattern/[flags]<br>语法 2 re = new RegExp("pattern",["flags"]) <br>参数<br>re<br>必选项。将要赋值为正则表达式模式的变量名。 <br>Pattern<br>必选项。要使用的正则表达式模式。如果使用语法 1，用 "/" 字符分隔模式。如果用语法 2，用引号将模式引起来。 </p>
<p>Flags <br>可选项。如果使用语法 2 要用引号将 flag 引起来。标志可以组合使用，可用的有： <br>g （全文查找出现的所有 pattern） <br>i （忽略大小写） <br>m （多行查找） <br>示例<br>下面的示例创建一个包含正则表达式模式及相关标志的对象(re)，向您演示正则表达式对象的用法。在本例中，作为结果的正则表达式对象又用于 match 方法中：<br>function MatchDemo()<br>{<br>var r, re; // 声明变量。<br>var s = "The rain in Spain falls mainly in the plain";<br>re = new RegExp("ain","g"); // 创建正则表达式对象。<br>r = s.match(re); // 在字符串 s 中查找匹配。<br>return(r); <br>}<br>返回值： ain,ain,ain,ain<br>属性 lastIndex 属性 | source 属性<br>方法 compile 方法 | exec 方法 | test 方法<br>要求 版本 3<br>请参阅 RegExp 对象 | 正则表达式语法 | String 对象</p>
<p>exec 方法</p>
<p><br>用正则表达式模式在字符串中运行查找，并返回包含该查找结果的一个数组。<br>rgExp.exec(str)<br>参数<br>rgExp <br>必选项。包含正则表达式模式和可用标志的正则表达式对象。 <br>str <br>必选项。要在其中执行查找的 String 对象或字符串文字。 <br>说明<br>如 果 exec 方法没有找到匹配，则它返回 null。如果它找到匹配，则 exec 方法返回一个数组，并且更新全局 RegExp 对象的属性，以反映匹配结果。数组的0元素包含了完整的匹配，而第1到n元素中包含的是匹配中出现的任意一个子匹配。这相当于没有设置全局标志 (g) 的 match 方法。<br>如果为正则表达式设置了全局标志，exec 从以 lastIndex 的值指示的位置开始查找。如果没有设置全局标志，exec 忽略 lastIndex 的值，从字符串的起始位置开始搜索。<br>exec 方法返回的数组有三个属性，分别是 input、index 和 lastIndex。Input 属性包含了整个被查找的字符串。Index 属性中包含了整个被查找字符串中被匹配的子字符串的位置。LastIndex 属性中包含了匹配中最后一个字符的下一个位置。<br>示例<br>下面的例子举例说明了 exec 方法的用法：<br>function RegExpTest()<br>{<br>var ver = Number(ScriptEngineMajorVersion() + "." + ScriptEngineMinorVersion())<br>if (ver &gt;= 5.5){ // 测试 JScript 的版本。<br>var src = "The rain in Spain falls mainly in the plain.";<br>var re = /\w+/g; // 创建正则表达式模式。<br>var arr;<br>while ((arr = re.exec(src)) != null)<br>document.write(arr.index + "-" + arr.lastIndex + arr + "\t");<br>}<br>else{<br>alert("请使用 JScript 的更新版本");<br>}<br>}<br>返回值：0-3The 4-8rain 9-11in 12-17Spain 18-23falls 24-30mainly 31-33in 34-37the 38-43plain</p>
<p><br>test 方法</p>
<p><br>返回一个 Boolean 值，它指出在被查找的字符串中是否存在模式。<br>rgexp.test(str) <br>参数<br>rgexp<br>必选项。包含正则表达式模式或可用标志的正则表达式对象。 <br>str <br>必选项。要在其上测试查找的字符串。 <br>说明<br>test 方法检查在字符串中是否存在一个模式，如果存在则返回 true，否则就返回 false。<br>全局 RegExp 对象的属性不由 test 方法来修改。<br>示例<br>下面的例子举例说明了 test 方法的用法：<br>function TestDemo(re, s)<br>{<br>var s1; // 声明变量。<br>// 检查字符串是否存在正则表达式。<br>if (re.test(s)) // 测试是否存在。<br>s1 = " contains "; // s 包含模式。<br>else<br>s1 = " does not contain "; // s 不包含模式。<br>return("'" + s + "'" + s1 + "'"+ re.source + "'"); // 返回字符串。<br>}<br>函数调用：document.write (TestDemo(/ain+/ ,"The rain in Spain falls mainly in the plain."));<br>返回值：'The rain in Spain falls mainly in the plain.' contains 'ain+'</p>
<p><br>match 方法</p>
<p><br>使用正则表达式模式对字符串执行查找，并将包含查找的结果作为数组返回。<br>stringObj.match(rgExp) <br>参数<br>stringObj <br>必选项。对其进行查找的 String 对象或字符串文字。 <br>rgExp <br>必选项。为包含正则表达式模式和可用标志的正则表达式对象。也可以是包含正则表达式模式和可用标志的变量名或字符串文字。 <br>说明<br>如果 match 方法没有找到匹配，返回 null。如果找到匹配返回一个数组并且更新全局 RegExp 对象的属性以反映匹配结果。<br>match 方法返回的数组有三个属性：input、index 和 lastIndex。Input 属性包含整个的被查找字符串。Index 属性包含了在整个被查找字符串中匹配的子字符串的位置。LastIndex 属性包含了最后一次匹配中最后一个字符的下一个位置。<br>如果没有设置全局标志 (g)，数组的 0 元素包含整个匹配，而第 1 到 n 元素包含了匹配中曾出现过的任一个子匹配。这相当于没有设置全局标志的 exec 方法。如果设置了全局标志，元素 0 到 n 中包含所有匹配。<br>示例<br>下面的示例演示了match 方法的用法：<br>function MatchDemo()<br>{<br>var r, re; // 声明变量。<br>var s = "The rain in Spain falls mainly in the plain";<br>re = /ain/i; // 创建正则表达式模式。<br>r = s.match(re); // 尝试匹配搜索字符串。<br>return(r); // 返回第一次出现 "ain" 的地方。<br>}<br>返回值：ain<br>本示例说明带 g 标志设置的 match 方法的用法。<br>function MatchDemo()<br>{<br>var r, re; // 声明变量。<br>var s = "The rain in Spain falls mainly in the plain";<br>re = /ain/ig; // 创建正则表达式模式。<br>r = s.match(re); // 尝试去匹配搜索字符串。<br>return(r); // 返回的数组包含了所有 "ain" <br>// 出现的四个匹配。<br>}<br>返回值：ain,ain,ain,ain<br>上面几行代码演示了字符串文字的 match 方法的用法。<br>var r, re = "Spain";<br>r = "The rain in Spain".replace(re, "Canada");<br>return r;<br>返回值：The rain in Canada</p>
<p><br>search 方法</p>
<p><br>返回与正则表达式查找内容匹配的第一个子字符串的位置。<br>stringObj.search(rgExp)<br>参数<br>stringObj <br>必选项。要在其上进行查找的 String 对象或字符串文字。 <br>rgExp <br>必选项。包含正则表达式模式和可用标志的正则表达式对象。 <br>说明<br>search 方法指明是否存在相应的匹配。如果找到一个匹配，search 方法将返回一个整数值，指明这个匹配距离字符串开始的偏移位置。如果没有找到匹配，则返回 -1。<br>示例<br>下面的示例演示了 search 方法的用法。<br>function SearchDemo()<br>{<br>var r, re; // 声明变量。<br>var s = "The rain in Spain falls mainly in the plain.";<br>re = /falls/i; // 创建正则表达式模式。<br>r = s.search(re); // 查找字符串。<br>return(r); // 返回 Boolean 结果。<br>}<br>返回值：18</p>
<p><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <br></p>
<img src ="http://www.blogjava.net/masen/aggbug/138106.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/masen/" target="_blank">Masen</a> 2007-08-20 13:20 <a href="http://www.blogjava.net/masen/articles/138106.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>验证日期正则表达试</title><link>http://www.blogjava.net/masen/articles/138105.html</link><dc:creator>Masen</dc:creator><author>Masen</author><pubDate>Mon, 20 Aug 2007 05:18:00 GMT</pubDate><guid>http://www.blogjava.net/masen/articles/138105.html</guid><wfw:comment>http://www.blogjava.net/masen/comments/138105.html</wfw:comment><comments>http://www.blogjava.net/masen/articles/138105.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/masen/comments/commentRss/138105.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/masen/services/trackbacks/138105.html</trackback:ping><description><![CDATA[这里是判断yyyy-mm-dd这种格式的，基本上把闰年和2月等的情况都考虑进去了，不过我已经忘了在哪里找到的。 <br><br>^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-))$ <br><br><br><br>下面的是加了时间验证的 <br><br>^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-)) (20|21|22|23|[0-1]?\d):[0-5]?\d:[0-5]?\d$ <br>
<img src ="http://www.blogjava.net/masen/aggbug/138105.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/masen/" target="_blank">Masen</a> 2007-08-20 13:18 <a href="http://www.blogjava.net/masen/articles/138105.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>正则表达式大全</title><link>http://www.blogjava.net/masen/articles/123365.html</link><dc:creator>Masen</dc:creator><author>Masen</author><pubDate>Mon, 11 Jun 2007 04:59:00 GMT</pubDate><guid>http://www.blogjava.net/masen/articles/123365.html</guid><wfw:comment>http://www.blogjava.net/masen/comments/123365.html</wfw:comment><comments>http://www.blogjava.net/masen/articles/123365.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/masen/comments/commentRss/123365.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/masen/services/trackbacks/123365.html</trackback:ping><description><![CDATA[<p><strong>前言</strong></p>
<p>正则表达式是烦琐的，但是强大的，学会之后的应用会让你除了提高效率外，会给你带来绝对的成就感。只要认真去阅读这些资料，加上应用的时候进行一定的参考，掌握正则表达式不是问题。</p>
<p><strong>索引</strong></p>
<p><a href="file:///D:/LinkToneCodes/Tone/ToneRobot/正则表达式(regular%20expression).htm#1._引子" target=_blank rel=nofollow><font color=#0000ff size=2><u>1._引子</u></font></a><font size=2><br><a href="file:///D:/LinkToneCodes/Tone/ToneRobot/正则表达式(regular%20expression).htm#2._正则表达式的历史" target=_blank rel=nofollow><font color=#0000ff><u>2._正则表达式的历史</u></font></a><br></font><a href="file:///D:/LinkToneCodes/Tone/ToneRobot/正则表达式(regular%20expression).htm#3._正则表达式定义" target=_blank rel=nofollow><font color=#0000ff size=2><u>3._正则表达式定义</u></font></a></p>
<blockquote>
<p><a href="file:///D:/LinkToneCodes/Tone/ToneRobot/正则表达式(regular%20expression).htm#3.1_普通字符" target=_blank rel=nofollow><font color=#0000ff size=2><u>3.1_普通字符</u></font></a><font size=2><br><a href="file:///D:/LinkToneCodes/Tone/ToneRobot/正则表达式(regular%20expression).htm#3.2_非打印字符" target=_blank rel=nofollow><font color=#0000ff><u>3.2_非打印字符</u></font></a><br><a href="file:///D:/LinkToneCodes/Tone/ToneRobot/正则表达式(regular%20expression).htm#3.3_特殊字符" target=_blank rel=nofollow><font color=#0000ff><u>3.3_特殊字符</u></font></a><br><a href="file:///D:/LinkToneCodes/Tone/ToneRobot/正则表达式(regular%20expression).htm#3.4_限定符" target=_blank rel=nofollow><font color=#0000ff><u>3.4_限定符</u></font></a><br><a href="file:///D:/LinkToneCodes/Tone/ToneRobot/正则表达式(regular%20expression).htm#3.5_定位符" target=_blank rel=nofollow><font color=#0000ff><u>3.5_定位符</u></font></a><br><a href="file:///D:/LinkToneCodes/Tone/ToneRobot/正则表达式(regular%20expression).htm#3.6_选择" target=_blank rel=nofollow><font color=#0000ff><u>3.6_选择</u></font></a><br></font><a href="file:///D:/LinkToneCodes/Tone/ToneRobot/正则表达式(regular%20expression).htm#3.7_后向引用" target=_blank rel=nofollow><font color=#0000ff size=2><u>3.7_后向引用</u></font></a></p>
</blockquote>
<p><a href="file:///D:/LinkToneCodes/Tone/ToneRobot/正则表达式(regular%20expression).htm#4._各种操作符的运算优先级" target=_blank rel=nofollow><font color=#0000ff size=2><u>4._各种操作符的运算优先级</u></font></a><font size=2><br><a href="file:///D:/LinkToneCodes/Tone/ToneRobot/正则表达式(regular%20expression).htm#5._全部符号解释" target=_blank rel=nofollow><font color=#0000ff><u>5._全部符号解释</u></font></a><br><a href="file:///D:/LinkToneCodes/Tone/ToneRobot/正则表达式(regular%20expression).htm#6._部分例子" target=_blank rel=nofollow><font color=#0000ff><u>6._部分例子</u></font></a><br></font><a href="file:///D:/LinkToneCodes/Tone/ToneRobot/正则表达式(regular%20expression).htm#7._正则表达式匹配规则" target=_blank rel=nofollow><font color=#0000ff size=2><u>7._正则表达式匹配规则</u></font></a></p>
<blockquote>
<p><a href="file:///D:/LinkToneCodes/Tone/ToneRobot/正则表达式(regular%20expression).htm#7.1_基本模式匹配" target=_blank rel=nofollow><font color=#0000ff size=2><u>7.1_基本模式匹配</u></font></a><font size=2><br><a href="file:///D:/LinkToneCodes/Tone/ToneRobot/正则表达式(regular%20expression).htm#7.2_字符簇" target=_blank rel=nofollow><font color=#0000ff><u>7.2_字符簇</u></font></a><br></font><a href="file:///D:/LinkToneCodes/Tone/ToneRobot/正则表达式(regular%20expression).htm#7.3_确定重复出现" target=_blank rel=nofollow><font color=#0000ff size=2><u>7.3_确定重复出现</u></font></a></p>
</blockquote><u><font color=#0000ff>
<hr>
</font></u>
<h2><a target=_blank rel=nofollow name=1._引子>1. 引子</a></h2>
<p>　　目前，正则表达式已经在很多软件中得到广泛的应用，包括*nix（Linux, Unix等），HP等操作系统，PHP，C#，Java等开发环境，以及很多的应用软件中，都可以看到正则表达式的影子。</p>
<p>　　正则表达式的使用，可以通过简单的办法来实现强大的功能。为了简单有效而又不失强大，造成了正则表达式代码的难度较大，学习起来也不是很容易，所以需要付出一些努力才行，入门之后参照一定的参考，使用起来还是比较简单有效的。</p>
<blockquote>
<p>例子：<span style="BACKGROUND-COLOR: #00ffff"> ^.+@.+\\..+$ </span></p>
</blockquote>
<p>　　这样的代码曾经多次把我自己给吓退过。可能很多人也是被这样的代码给吓跑的吧。继续阅读本文将让你也可以自由应用这样的代码。</p>
<p>　　注意：这里的第7部分跟前面的内容看起来似乎有些重复，目的是把前面表格里的部分重新描述了一次，目的是让这些内容更容易理解。</p>
<h2><strong><a target=_blank rel=nofollow name=2._正则表达式的历史>2. 正则表达式的历史</a></strong></h2>
<div id=nstext valign="bottom">　　正则表达式的&#8220;祖先&#8221;可以一直上溯至对人类神经系统如何工作的早期研究。Warren McCulloch 和 Walter Pitts 这两位神经生理学家研究出一种数学方式来描述这些神经网络。
<p>　　1956 年, 一位叫 Stephen Kleene 的数学家在 McCulloch 和 Pitts 早期工作的基础上，发表了一篇标题为&#8220;神经网事件的表示法&#8221;的论文，引入了正则表达式的概念。正则表达式就是用来描述他称为&#8220;正则集的代数&#8221;的表达式，因此采用&#8220;正则表达式&#8221;这个术语。</p>
<p>　　随后，发现可以将这一工作应用于使用 Ken Thompson 的计算搜索算法的一些早期研究，Ken Thompson 是 Unix 的主要发明人。正则表达式的第一个实用应用程序就是 Unix 中的 <em>qed </em>编辑器。</p>
<p>　　如他们所说，剩下的就是众所周知的历史了。从那时起直至现在正则表达式都是基于文本的编辑器和搜索工具中的一个重要部分。</p>
</div>
<p>　</p>
<h2><strong><a target=_blank rel=nofollow name=3._正则表达式定义>3. 正则表达式定义</a></strong></h2>
<p>　　正则表达式(regular expression)描述了一种字符串匹配的模式，可以用来检查一个串是否含有某种子串、将匹配的子串做替换或者从某个串中取出符合某个条件的子串等。</p>
<blockquote>
<ul>
    <li><span style="BACKGROUND-COLOR: #ffff00">列目录时，　dir *.txt或ls *.txt中的*.txt就</span><font color=#ff0000><span style="BACKGROUND-COLOR: #ffff00">不</span></font><span style="BACKGROUND-COLOR: #ffff00">是一个正则表达式,因为这里*与正则式的*的含义是不同的。</span> </li>
</ul>
</blockquote>
<p>　　正则表达式是由普通字符（例如字符 a 到 z）以及特殊字符（称为元字符）组成的文字模式。正则表达式作为一个模板，将某个字符模式与所搜索的字符串进行匹配。</p>
<h3><strong><a target=_blank rel=nofollow name=3.1_普通字符>3.1 普通字符</a></strong></h3>
<p>　　由所有那些未显式指定为元字符的打印和非打印字符组成。这包括所有的大写和小写字母字符，所有数字，所有标点符号以及一些符号。 </p>
<h3><a target=_blank rel=nofollow name=3.2_非打印字符>3.2 非打印字符</a></h3>
<table cellSpacing=1 cellPadding=3 border=0>
    <tbody>
        <tr>
            <th style="FONT-SIZE: 12px" align=left>字符 </th>
            <th style="FONT-SIZE: 12px" align=left>含义</th>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\cx </td>
            <td style="FONT-SIZE: 12px">匹配由x指明的控制字符。例如， \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则，将 c 视为一个原义的 'c' 字符。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\f </td>
            <td style="FONT-SIZE: 12px">匹配一个换页符。等价于 \x0c 和 \cL。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\n </td>
            <td style="FONT-SIZE: 12px">匹配一个换行符。等价于 \x0a 和 \cJ。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\r </td>
            <td style="FONT-SIZE: 12px">匹配一个回车符。等价于 \x0d 和 \cM。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\s </td>
            <td style="FONT-SIZE: 12px">匹配任何空白字符，包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\S </td>
            <td style="FONT-SIZE: 12px">匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\t </td>
            <td style="FONT-SIZE: 12px">匹配一个制表符。等价于 \x09 和 \cI。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\v </td>
            <td style="FONT-SIZE: 12px">匹配一个垂直制表符。等价于 \x0b 和 \cK。</td>
        </tr>
    </tbody>
</table>
<br>　
<h3><a target=_blank rel=nofollow name=3.3_特殊字符>3.3 特殊字符</a></h3>
　　所谓特殊字符，就是一些有特殊含义的字符，如上面说的"*.txt"中的*，简单的说就是表示任何字符串的意思。如果要查找文件名中有＊的文件，则需要对＊进行转义，即在其前加一个\。ls \*.txt。正则表达式有以下特殊字符。
<p>　</p>
<table cellSpacing=1 cellPadding=3 border=0>
    <tbody>
        <tr>
            <th style="FONT-SIZE: 12px" align=left>特别字符</th>
            <th style="FONT-SIZE: 12px" align=left>说明</th>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">$</td>
            <td style="FONT-SIZE: 12px">匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性，则 $ 也匹配 '\n' 或 '\r'。要匹配 $ 字符本身，请使用 \$。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">( )</td>
            <td style="FONT-SIZE: 12px">标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符，请使用 \( 和 \)。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">*</td>
            <td style="FONT-SIZE: 12px">匹配前面的子表达式零次或多次。要匹配 * 字符，请使用 \*。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">+</td>
            <td style="FONT-SIZE: 12px">匹配前面的子表达式一次或多次。要匹配 + 字符，请使用 \+。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">.</td>
            <td style="FONT-SIZE: 12px">匹配除换行符 \n之外的任何单字符。要匹配 .，请使用 \。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">[ </td>
            <td style="FONT-SIZE: 12px">标记一个中括号表达式的开始。要匹配 [，请使用 \[。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">?</td>
            <td style="FONT-SIZE: 12px">匹配前面的子表达式零次或一次，或指明一个非贪婪限定符。要匹配 ? 字符，请使用 \?。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\</td>
            <td style="FONT-SIZE: 12px">将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如， 'n' 匹配字符 'n'。'\n' 匹配换行符。序列 '\\' 匹配 "\"，而 '\(' 则匹配 "("。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">^</td>
            <td style="FONT-SIZE: 12px">匹配输入字符串的开始位置，除非在方括号表达式中使用，此时它表示不接受该字符集合。要匹配 ^ 字符本身，请使用 \^。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">{</td>
            <td style="FONT-SIZE: 12px">标记限定符表达式的开始。要匹配 {，请使用 \{。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">|</td>
            <td style="FONT-SIZE: 12px">指明两项之间的一个选择。要匹配 |，请使用 \|。</td>
        </tr>
    </tbody>
</table>
<blockquote>
<ul>
    <li><strong style="FONT-WEIGHT: 400; BACKGROUND-COLOR: #ffff00">　　构造正则表达式的方法和创建数学表达式的方法一样。也就是用多种元字符与操作符将小的表达式结合在一起来创建更大的表达式。正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。</strong> </li>
</ul>
</blockquote>
<p>　</p>
<h3><a target=_blank rel=nofollow name=3.4_限定符>3.4 限定符</a></h3>
　　限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有*或+或?或{n}或{n,}或{n,m}共6种。<br>*、+和?限定符都是贪婪的，因为它们会尽可能多的匹配文字，只有在它们的后面加上一个?就可以实现非贪婪或最小匹配。<br>　　正则表达式的限定符有：<br>　
<table cellSpacing=1 cellPadding=3 border=0>
    <tbody>
        <tr>
            <th style="FONT-SIZE: 12px" align=left>字符 </th>
            <th style="FONT-SIZE: 12px" align=left>描述</th>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">* </td>
            <td style="FONT-SIZE: 12px">匹配前面的子表达式零次或多次。例如，zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">+ </td>
            <td style="FONT-SIZE: 12px">匹配前面的子表达式一次或多次。例如，'zo+' 能匹配 "zo" 以及 "zoo"，但不能匹配 "z"。+ 等价于 {1,}。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">? </td>
            <td style="FONT-SIZE: 12px">匹配前面的子表达式零次或一次。例如，"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等价于 {0,1}。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">{n} </td>
            <td style="FONT-SIZE: 12px">n 是一个非负整数。匹配确定的 n 次。例如，'o{2}' 不能匹配 "Bob" 中的 'o'，但是能匹配 "food" 中的两个 o。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">{n,} </td>
            <td style="FONT-SIZE: 12px">n 是一个非负整数。至少匹配n 次。例如，'o{2,}' 不能匹配 "Bob" 中的 'o'，但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">{n,m} </td>
            <td style="FONT-SIZE: 12px">m 和 n 均为非负整数，其中n &lt;= m。最少匹配 n 次且最多匹配 m 次。例如，"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。</td>
        </tr>
    </tbody>
</table>
<h3><a target=_blank rel=nofollow name=3.5_定位符>3.5 定位符</a></h3>
　　用来描述字符串或单词的边界，^和$分别指字符串的开始与结束，\b描述单词的前或后边界，\B表示非单词边界。<font color=#ff0000>不能对定位符使用限定符。</font>
<h3><a target=_blank rel=nofollow name=3.6_选择>3.6 选择</a></h3>
　　用圆括号将所有选择项括起来，相邻的选择项之间用|分隔。但用圆括号会有一个副作用，是相关的匹配会被缓存，此时可用?:放在第一个选项前来消除这种副作用。<br>　　其中?:是非捕获元之一，还有两个非捕获元是?=和?!，这两个还有更多的含义，前者为正向预查，在任何开始匹配圆括号内的正则表达式模式的位置来匹配搜索字符串，后者为负向预查，在任何开始不匹配该正则表达式模式的位置来匹配搜索字符串。
<h3><a target=_blank rel=nofollow name=3.7_后向引用>3.7 后向引用</a></h3>
　　对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中，所捕获的每个子匹配都按照在正则表达式模式中从左至右所遇到的内容存储。存储子匹配的缓冲区编号从 1 开始，连续编号直至最大 99 个子表达式。每个缓冲区都可以使用 '\n' 访问，其中 n 为一个标识特定缓冲区的一位或两位十进制数。<br>　　可以使用非捕获元字符 '?:', '?=', or '?!' 来忽略对相关匹配的保存。
<h2><a target=_blank rel=nofollow name=4._各种操作符的运算优先级>4. 各种操作符的运算优先级</a></h2>
　　相同优先级的从左到右进行运算，不同优先级的运算先高后低。各种操作符的优先级从高到低如下：<br>　
<table cellSpacing=1 cellPadding=3 border=0>
    <tbody>
        <tr>
            <th style="FONT-SIZE: 12px" align=left>操作符 </th>
            <th style="FONT-SIZE: 12px" align=left>描述</th>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\ </td>
            <td style="FONT-SIZE: 12px">转义符</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">(), (?:), (?=), [] </td>
            <td style="FONT-SIZE: 12px">圆括号和方括号</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">*, +, ?, {n}, {n,}, {n,m} </td>
            <td style="FONT-SIZE: 12px">限定符</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">^, $, \anymetacharacter </td>
            <td style="FONT-SIZE: 12px">位置和顺序</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">| </td>
            <td style="FONT-SIZE: 12px">&#8220;或&#8221;操作</td>
        </tr>
    </tbody>
</table>
<h2><a target=_blank rel=nofollow name=5._全部符号解释>5. 全部符号解释</a></h2>
<table cellSpacing=1 cellPadding=3 border=0>
    <tbody>
        <tr>
            <th style="FONT-SIZE: 12px" align=left>字符 </th>
            <th style="FONT-SIZE: 12px" align=left>描述</th>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\ </td>
            <td style="FONT-SIZE: 12px">将下一个字符标记为一个特殊字符、或一个原义字符、或一个 向后引用、或一个八进制转义符。例如，'n' 匹配字符 "n"。'\n' 匹配一个换行符。序列 '\\' 匹配 "\" 而 "\(" 则匹配 "("。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">^ </td>
            <td style="FONT-SIZE: 12px">匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性，^ 也匹配 '\n' 或 '\r' 之后的位置。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">$ </td>
            <td style="FONT-SIZE: 12px">匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性，$ 也匹配 '\n' 或 '\r' 之前的位置。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">* </td>
            <td style="FONT-SIZE: 12px">匹配前面的子表达式零次或多次。例如，zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">+ </td>
            <td style="FONT-SIZE: 12px">匹配前面的子表达式一次或多次。例如，'zo+' 能匹配 "zo" 以及 "zoo"，但不能匹配 "z"。+ 等价于 {1,}。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">? </td>
            <td style="FONT-SIZE: 12px">匹配前面的子表达式零次或一次。例如，"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等价于 {0,1}。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">{n} </td>
            <td style="FONT-SIZE: 12px">n 是一个非负整数。匹配确定的 n 次。例如，'o{2}' 不能匹配 "Bob" 中的 'o'，但是能匹配 "food" 中的两个 o。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">{n,} </td>
            <td style="FONT-SIZE: 12px">n 是一个非负整数。至少匹配n 次。例如，'o{2,}' 不能匹配 "Bob" 中的 'o'，但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">{n,m} </td>
            <td style="FONT-SIZE: 12px">m 和 n 均为非负整数，其中n &lt;= m。最少匹配 n 次且最多匹配 m 次。例如，"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">? </td>
            <td style="FONT-SIZE: 12px">当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时，匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串，而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如，对于字符串 "oooo"，'o+?' 将匹配单个 "o"，而 'o+' 将匹配所有 'o'。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">. </td>
            <td style="FONT-SIZE: 12px">匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符，请使用象 '[.\n]' 的模式。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">(pattern) </td>
            <td style="FONT-SIZE: 12px">匹配 pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到，在VBScript 中使用 SubMatches 集合，在JScript 中则使用 $0&#8230;$9 属性。要匹配圆括号字符，请使用 '\(' 或 '\)'。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">(?:pattern) </td>
            <td style="FONT-SIZE: 12px">匹配 pattern 但不获取匹配结果，也就是说这是一个非获取匹配，不进行存储供以后使用。这在使用 "或" 字符 (|) 来组合一个模式的各个部分是很有用。例如， 'industr(?:y|ies) 就是一个比 'industry|industries' 更简略的表达式。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">(?=pattern) </td>
            <td style="FONT-SIZE: 12px">正向预查，在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配，也就是说，该匹配不需要获取供以后使用。例如，'Windows (?=95|98|NT|2000)' 能匹配 "Windows 2000" 中的 "Windows" ，但不能匹配 "Windows 3.1" 中的 "Windows"。预查不消耗字符，也就是说，在一个匹配发生后，在最后一次匹配之后立即开始下一次匹配的搜索，而不是从包含预查的字符之后开始。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">(?!pattern) </td>
            <td style="FONT-SIZE: 12px">负向预查，在任何不匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配，也就是说，该匹配不需要获取供以后使用。例如'Windows (?!95|98|NT|2000)' 能匹配 "Windows 3.1" 中的 "Windows"，但不能匹配 "Windows 2000" 中的 "Windows"。预查不消耗字符，也就是说，在一个匹配发生后，在最后一次匹配之后立即开始下一次匹配的搜索，而不是从包含预查的字符之后开始</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">x|y </td>
            <td style="FONT-SIZE: 12px">匹配 x 或 y。例如，'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 则匹配 "zood" 或 "food"。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">[xyz] </td>
            <td style="FONT-SIZE: 12px">字符集合。匹配所包含的任意一个字符。例如， '[abc]' 可以匹配 "plain" 中的 'a'。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">[^xyz] </td>
            <td style="FONT-SIZE: 12px">负值字符集合。匹配未包含的任意字符。例如， '[^abc]' 可以匹配 "plain" 中的'p'。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">[a-z] </td>
            <td style="FONT-SIZE: 12px">字符范围。匹配指定范围内的任意字符。例如，'[a-z]' 可以匹配 'a' 到 'z' 范围内的任意小写字母字符。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">[^a-z] </td>
            <td style="FONT-SIZE: 12px">负值字符范围。匹配任何不在指定范围内的任意字符。例如，'[^a-z]' 可以匹配任何不在 'a' 到 'z' 范围内的任意字符。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\b </td>
            <td style="FONT-SIZE: 12px">匹配一个单词边界，也就是指单词和空格间的位置。例如， 'er\b' 可以匹配"never" 中的 'er'，但不能匹配 "verb" 中的 'er'。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\B </td>
            <td style="FONT-SIZE: 12px">匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er'，但不能匹配 "never" 中的 'er'。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\cx </td>
            <td style="FONT-SIZE: 12px">匹配由 x 指明的控制字符。例如， \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则，将 c 视为一个原义的 'c' 字符。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\d </td>
            <td style="FONT-SIZE: 12px">匹配一个数字字符。等价于 [0-9]。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\D </td>
            <td style="FONT-SIZE: 12px">匹配一个非数字字符。等价于 [^0-9]。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\f </td>
            <td style="FONT-SIZE: 12px">匹配一个换页符。等价于 \x0c 和 \cL。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\n </td>
            <td style="FONT-SIZE: 12px">匹配一个换行符。等价于 \x0a 和 \cJ。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\r </td>
            <td style="FONT-SIZE: 12px">匹配一个回车符。等价于 \x0d 和 \cM。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\s </td>
            <td style="FONT-SIZE: 12px">匹配任何空白字符，包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\S </td>
            <td style="FONT-SIZE: 12px">匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\t </td>
            <td style="FONT-SIZE: 12px">匹配一个制表符。等价于 \x09 和 \cI。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\v </td>
            <td style="FONT-SIZE: 12px">匹配一个垂直制表符。等价于 \x0b 和 \cK。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\w </td>
            <td style="FONT-SIZE: 12px">匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\W </td>
            <td style="FONT-SIZE: 12px">匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\xn </td>
            <td style="FONT-SIZE: 12px">匹配 n，其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如，'\x41' 匹配 "A"。'\x041' 则等价于 '\x04' &amp; "1"。正则表达式中可以使用 ASCII 编码。.</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\num </td>
            <td style="FONT-SIZE: 12px">匹配 num，其中 num 是一个正整数。对所获取的匹配的引用。例如，'(.)\1' 匹配两个连续的相同字符。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\n </td>
            <td style="FONT-SIZE: 12px">标识一个八进制转义值或一个向后引用。如果 \n 之前至少 n 个获取的子表达式，则 n 为向后引用。否则，如果 n 为八进制数字 (0-7)，则 n 为一个八进制转义值。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\nm </td>
            <td style="FONT-SIZE: 12px">标识一个八进制转义值或一个向后引用。如果 \nm 之前至少有 nm 个获得子表达式，则 nm 为向后引用。如果 \nm 之前至少有 n 个获取，则 n 为一个后跟文字 m 的向后引用。如果前面的条件都不满足，若 n 和 m 均为八进制数字 (0-7)，则 \nm 将匹配八进制转义值 nm。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\nml </td>
            <td style="FONT-SIZE: 12px">如果 n 为八进制数字 (0-3)，且 m 和 l 均为八进制数字 (0-7)，则匹配八进制转义值 nml。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">\un </td>
            <td style="FONT-SIZE: 12px">匹配 n，其中 n 是一个用四个十六进制数字表示的 Unicode 字符。例如， \u00A9 匹配版权符号 (?)。</td>
        </tr>
    </tbody>
</table>
<p>　</p>
<h2><a target=_blank rel=nofollow name=6._部分例子>6. 部分例子</a></h2>
<table cellSpacing=1 cellPadding=3 border=0>
    <tbody>
        <tr>
            <th style="FONT-SIZE: 12px" align=left>正则表达式</th>
            <th style="FONT-SIZE: 12px" align=left>说明</th>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">/\b([a-z]+) \1\b/gi</td>
            <td style="FONT-SIZE: 12px">一个单词连续出现的位置</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">/(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)/ </td>
            <td style="FONT-SIZE: 12px">将一个URL解析为协议、域、端口及相对路径</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">/^(?:Chapter|Section) [1-9][0-9]{0,1}$/</td>
            <td style="FONT-SIZE: 12px">定位章节的位置</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">/[-a-z]/</td>
            <td style="FONT-SIZE: 12px">A至z共26个字母再加一个-号。</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">/ter\b/</td>
            <td style="FONT-SIZE: 12px">可匹配chapter，而不能terminal</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">/\Bapt/</td>
            <td style="FONT-SIZE: 12px">可匹配chapter，而不能aptitude</td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 12px">/Windows(?=95 |98 |NT )/</td>
            <td style="FONT-SIZE: 12px">可匹配Windows95或Windows98或WindowsNT,当找到一个匹配后，从Windows后面开始进行下一次的检索匹配。</td>
        </tr>
    </tbody>
</table>
<p>　</p>
<h2><a target=_blank rel=nofollow name=7._正则表达式匹配规则>7. 正则表达式匹配规则</a></h2>
<p><strong><a target=_blank rel=nofollow name=7.1_基本模式匹配>7.1 基本模式匹配</a></strong><br><br>　　一切从最基本的开始。模式，是正规表达式最基本的元素，它们是一组描述字符串特征的字符。模式可以很简单，由普通的字符串组成，也可以非常复杂，往往用特殊的字符表示一个范围内的字符、重复出现，或表示上下文。例如：</p>
<blockquote>
<p>^once </p>
</blockquote>
<p>　　这个模式包含一个特殊的字符^，表示该模式只匹配那些以once开头的字符串。例如该模式与字符串"once upon a time"匹配，与"There once was a man from NewYork"不匹配。正如如^符号表示开头一样，$符号用来匹配那些以给定模式结尾的字符串。</p>
<blockquote>
<p>bucket$ </p>
</blockquote>
<p>　　这个模式与"Who kept all of this cash in a bucket"匹配，与"buckets"不匹配。字符^和$同时使用时，表示精确匹配（字符串与模式一样）。例如：</p>
<blockquote>
<p>^bucket$ </p>
</blockquote>
<p>　　只匹配字符串"bucket"。如果一个模式不包括^和$，那么它与任何包含该模式的字符串匹配。例如：模式</p>
<blockquote>
<p>once </p>
</blockquote>
<p>与字符串</p>
<blockquote>
<p>There once was a man from NewYork<br>Who kept all of his cash in a bucket.</p>
</blockquote>
<p>是匹配的。<br><br>　　在该模式中的字母(o-n-c-e)是字面的字符，也就是说，他们表示该字母本身，数字也是一样的。其他一些稍微复杂的字符，如标点符号和白字符（空格、制表符等），要用到转义序列。所有的转义序列都用反斜杠(\)打头。制表符的转义序列是：\t。所以如果我们要检测一个字符串是否以制表符开头，可以用这个模式：</p>
<blockquote>
<p>^\t </p>
</blockquote>
<p>类似的，用\n表示&#8220;新行&#8221;，\r表示回车。其他的特殊符号，可以用在前面加上反斜杠，如反斜杠本身用\\表示，句号.用\.表示，以此类推。<br><br><strong><a target=_blank rel=nofollow name=7.2_字符簇>7.2 字符簇</a></strong><br><br>在INTERNET的程序中，正规表达式通常用来验证用户的输入。当用户提交一个form以后，要判断输入的电话号码、地址、EMAIL地址、信用卡号码等是否有效，用普通的基于字面的字符是不够的。<br><br>所以要用一种更自由的描述我们要的模式的办法，它就是字符簇。要建立一个表示所有元音字符的字符簇，就把所有的元音字符放在一个方括号里：</p>
<blockquote>
<p>[AaEeIiOoUu] </p>
</blockquote>
<p>这个模式与任何元音字符匹配，但只能表示一个字符。用连字号可以表示一个字符的范围，如：</p>
<blockquote>
<p>[a-z] //匹配所有的小写字母 <br>[A-Z] //匹配所有的大写字母 <br>[a-zA-Z] //匹配所有的字母 <br>[0-9] //匹配所有的数字 <br>[0-9\.\-] //匹配所有的数字，句号和减号 <br>[ \f\r\t\n] //匹配所有的白字符 </p>
</blockquote>
<p>同样的，这些也只表示一个字符，这是一个非常重要的。如果要匹配一个由一个小写字母和一位数字组成的字符串，比如"z2"、"t6"或"g7"，但不是"ab2"、"r2d3" 或"b52"的话，用这个模式：</p>
<blockquote>
<p>^[a-z][0-9]$ </p>
</blockquote>
<p>尽管[a-z]代表26个字母的范围，但在这里它只能与第一个字符是小写字母的字符串匹配。<br><br>前面曾经提到^表示字符串的开头，但它还有另外一个含义。当在一组方括号里使用^是，它表示&#8220;非&#8221;或&#8220;排除&#8221;的意思，常常用来剔除某个字符。还用前面的例子，我们要求第一个字符不能是数字：</p>
<blockquote>
<p>^[^0-9][0-9]$ </p>
</blockquote>
<p>这个模式与"&amp;5"、"g7"及"-2"是匹配的，但与"12"、"66"是不匹配的。下面是几个排除特定字符的例子：</p>
<blockquote>
<p>[^a-z] //除了小写字母以外的所有字符 <br>[^\\\/\^] //除了(\)(/)(^)之外的所有字符 <br>[^\"\'] //除了双引号(")和单引号(')之外的所有字符 </p>
</blockquote>
<p>特殊字符"." (点，句号)在正规表达式中用来表示除了&#8220;新行&#8221;之外的所有字符。所以模式"^.5$"与任何两个字符的、以数字5结尾和以其他非&#8220;新行&#8221;字符开头的字符串匹配。模式"."可以匹配任何字符串，除了空串和只包括一个&#8220;新行&#8221;的字符串。<br><br>PHP的正规表达式有一些内置的通用字符簇，列表如下：</p>
<blockquote>
<p>字符簇 含义 <br>[[:alpha:]] 任何字母 <br>[[:digit:]] 任何数字 <br>[[:alnum:]] 任何字母和数字 <br>[[:space:]] 任何白字符 <br>[[:upper:]] 任何大写字母 <br>[[:lower:]] 任何小写字母 <br>[[:punct:]] 任何标点符号 <br>[[:xdigit:]] 任何16进制的数字，相当于[0-9a-fA-F] </p>
</blockquote>
<p><strong><a target=_blank rel=nofollow name=7.3_确定重复出现>7.3 确定重复出现</a></strong><br><br>到现在为止，你已经知道如何去匹配一个字母或数字，但更多的情况下，可能要匹配一个单词或一组数字。一个单词有若干个字母组成，一组数字有若干个单数组成。跟在字符或字符簇后面的花括号({})用来确定前面的内容的重复出现的次数。 </p>
<blockquote>
<p>字符簇 含义 <br>^[a-zA-Z_]$ 所有的字母和下划线 <br>^[[:alpha:]]{3}$ 所有的3个字母的单词 <br>^a$ 字母a <br>^a{4}$ aaaa <br>^a{2,4}$ aa,aaa或aaaa <br>^a{1,3}$ a,aa或aaa <br>^a{2,}$ 包含多于两个a的字符串 <br>^a{2,} 如：aardvark和aaab，但apple不行 <br>a{2,} 如：baad和aaa，但Nantucket不行 <br>\t{2} 两个制表符 <br>.{2} 所有的两个字符 </p>
</blockquote>
<p>这些例子描述了花括号的三种不同的用法。一个数字，{x}的意思是&#8220;前面的字符或字符簇只出现x次&#8221;；一个数字加逗号，{x,}的意思是&#8220;前面的内容出现x或更多的次数&#8221;；两个用逗号分隔的数字，{x,y}表示&#8220;前面的内容至少出现x次，但不超过y次&#8221;。我们可以把模式扩展到更多的单词或数字：</p>
<blockquote>
<p>^[a-zA-Z0-9_]{1,}$ //所有包含一个以上的字母、数字或下划线的字符串 <br>^[0-9]{1,}$ //所有的正数 <br>^\-{0,1}[0-9]{1,}$ //所有的整数 <br>^\-{0,1}[0-9]{0,}\.{0,1}[0-9]{0,}$ //所有的小数 </p>
</blockquote>
<p>最后一个例子不太好理解，是吗？这么看吧：与所有以一个可选的负号(\-{0,1})开头(^)、跟着0个或更多的数字([0-9]{0,})、和一个可选的小数点(\.{0,1})再跟上0个或多个数字([0-9]{0,})，并且没有其他任何东西($)。下面你将知道能够使用的更为简单的方法。<br><br>特殊字符"?"与{0,1}是相等的，它们都代表着：&#8220;0个或1个前面的内容&#8221;或&#8220;前面的内容是可选的&#8221;。所以刚才的例子可以简化为：</p>
<blockquote>
<p>^\-?[0-9]{0,}\.?[0-9]{0,}$ </p>
</blockquote>
<p>特殊字符"*"与{0,}是相等的，它们都代表着&#8220;0个或多个前面的内容&#8221;。最后，字符"+"与 {1,}是相等的，表示&#8220;1个或多个前面的内容&#8221;，所以上面的4个例子可以写成：</p>
<blockquote>
<p>^[a-zA-Z0-9_]+$ //所有包含一个以上的字母、数字或下划线的字符串 <br>^[0-9]+$ //所有的正数 <br>^\-?[0-9]+$ //所有的整数 <br>^\-?[0-9]*\.?[0-9]*$ //所有的小数 </p>
</blockquote>
<p>当然这并不能从技术上降低正规表达式的复杂性，但可以使它们更容易阅读。</p>
<img src ="http://www.blogjava.net/masen/aggbug/123365.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/masen/" target="_blank">Masen</a> 2007-06-11 12:59 <a href="http://www.blogjava.net/masen/articles/123365.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>文件路径的处理(转帖) </title><link>http://www.blogjava.net/masen/articles/108656.html</link><dc:creator>Masen</dc:creator><author>Masen</author><pubDate>Thu, 05 Apr 2007 03:47:00 GMT</pubDate><guid>http://www.blogjava.net/masen/articles/108656.html</guid><wfw:comment>http://www.blogjava.net/masen/comments/108656.html</wfw:comment><comments>http://www.blogjava.net/masen/articles/108656.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/masen/comments/commentRss/108656.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/masen/services/trackbacks/108656.html</trackback:ping><description><![CDATA[<p><font size=3>1.如何获得当前文件路径</font> </p>
<p><font size=3>常用：</font> </p>
<p><font size=3>字符串类型：System.getProperty("user.dir");</font> </p>
<p><font size=3>综合：</font> </p>
<p><font size=3>package com.zcjl.test.base;<br>import java.io.File;<br>public class Test {<br>&nbsp;&nbsp;&nbsp; public static void main(String[] args) throws Exception {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(<br></font><font size=3><font color=#ff0000>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread.currentThread().getContextClassLoader().getResource(""));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(Test.class.getClassLoader().getResource(""));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(ClassLoader.getSystemResource(""));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(Test.class.getResource(""));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(Test.class.getResource("/"));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(new File("").getAbsolutePath());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(System.getProperty("user.dir"));</font> <br>&nbsp;&nbsp;&nbsp; }<br>}</font> </p>
<p><font size=3>2.Web服务中</font> </p>
<p><font size=3>(1).Weblogic</font> </p>
<p><font size=3>WebApplication的系统文件根目录是你的weblogic安装所在根目录。<br>例如：如果你的weblogic安装在c:\bea\weblogic700.....<br>那么，你的文件根路径就是c:\.<br>所以，有两种方式能够让你访问你的服务器端的文件：<br>a.使用绝对路径：<br>比如将你的参数文件放在c:\yourconfig\yourconf.properties，<br>直接使用 new FileInputStream("yourconfig/yourconf.properties");<br>b.使用相对路径：<br>相对路径的根目录就是你的webapplication的根路径，即WEB-INF的上一级目录，将你的参数文件放在yourwebapp\yourconfig\yourconf.properties，<br>这样使用：<br>new FileInputStream("./yourconfig/yourconf.properties");<br>这两种方式均可，自己选择。</font> </p>
<p><font size=3>(2).Tomcat</font> </p>
<p><font size=3>在类中输出System.getProperty("user.dir");显示的是%Tomcat_Home%/bin</font> </p>
<p><font size=3>(3).Resin</font> </p>
<p><font size=3>不是你的JSP放的相对路径,是JSP引擎执行这个JSP编译成SERVLET<br>的路径为根.比如用新建文件法测试File f = new File("a.htm");<br>这个a.htm在resin的安装目录下 </font></p>
<p><font color=#ff0000 size=3>(4).如何读相对路径哪？</font> </p>
<p><font color=#ff0000 size=3>在Java文件中getResource或getResourceAsStream均可</font> </p>
<p><font color=#ff0000 size=3>例：getClass().getResourceAsStream(filePath);//filePath可以是"/filename",这里的/代表web发布根路径下WEB-INF/classes</font> </p>
<p><font size=3>(5).获得文件真实路径</font> </p>
<p><font size=3>string&nbsp; file_real_path=request.getRealPath("mypath/filename");&nbsp; </font></p>
<p><font size=3>通常使用request.getRealPath("/");&nbsp; </font></p>
<p><font size=3>3.文件操作的类</font> </p>
<p><font size=3>import java.io.*;<br>import java.net.*;<br>import java.util.*;<br>//import javax.swing.filechooser.*;<br>//import org.jr.swing.filter.*;</font> </p>
<p><font size=3>/**<br>* 此类中封装一些常用的文件操作。<br>* 所有方法都是静态方法，不需要生成此类的实例，<br>* 为避免生成此类的实例，构造方法被申明为private类型的。<br>* @since&nbsp; 0.1<br>*/</font> </p>
<p><font size=3>public class FileUtil {<br>&nbsp; /**<br>&nbsp;&nbsp; * 私有构造方法，防止类的实例化，因为工具类不需要实例化。<br>&nbsp;&nbsp; */<br>&nbsp; private FileUtil() {</font> </p>
<p><font size=3>&nbsp; }</font> </p>
<p><font size=3>&nbsp; /**<br>&nbsp;&nbsp; * 修改文件的最后访问时间。<br>&nbsp;&nbsp; * 如果文件不存在则创建该文件。<br>&nbsp;&nbsp; * &lt;b&gt;目前这个方法的行为方式还不稳定，主要是方法有些信息输出，这些信息输出是否保留还在考</font> </p>
<p><font size=3>虑中。&lt;/b&gt;<br>&nbsp;&nbsp; * @param file 需要修改最后访问时间的文件。<br>&nbsp;&nbsp; * @since&nbsp; 0.1<br>&nbsp;&nbsp; */<br>&nbsp; public static void touch(File file) {<br>&nbsp;&nbsp;&nbsp; long currentTime = System.currentTimeMillis();<br>&nbsp;&nbsp;&nbsp; if (!file.exists()) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.err.println("file not found:" + file.getName());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.err.println("Create a new file:" + file.getName());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (file.createNewFile()) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp; System.out.println("Succeeded!");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp; System.err.println("Create file failed!");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (IOException e) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp; System.err.println("Create file failed!");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; boolean result = file.setLastModified(currentTime);<br>&nbsp;&nbsp;&nbsp; if (!result) {<br>&nbsp;&nbsp;&nbsp; //&nbsp; System.err.println("touch failed: " + file.getName());<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp; }</font> </p>
<p><font size=3>&nbsp; /**<br>&nbsp;&nbsp; * 修改文件的最后访问时间。<br>&nbsp;&nbsp; * 如果文件不存在则创建该文件。<br>&nbsp;&nbsp; * &lt;b&gt;目前这个方法的行为方式还不稳定，主要是方法有些信息输出，这些信息输出是否保留还在考</font> </p>
<p><font size=3>虑中。&lt;/b&gt;<br>&nbsp;&nbsp; * @param fileName 需要修改最后访问时间的文件的文件名。<br>&nbsp;&nbsp; * @since&nbsp; 0.1<br>&nbsp;&nbsp; */<br>&nbsp; public static void touch(String fileName) {<br>&nbsp;&nbsp;&nbsp; File file = new File(fileName);<br>&nbsp;&nbsp;&nbsp; touch(file);<br>&nbsp; }</font> </p>
<p><font size=3>&nbsp; /**<br>&nbsp;&nbsp; * 修改文件的最后访问时间。<br>&nbsp;&nbsp; * 如果文件不存在则创建该文件。<br>&nbsp;&nbsp; * &lt;b&gt;目前这个方法的行为方式还不稳定，主要是方法有些信息输出，这些信息输出是否保留还在考</font> </p>
<p><font size=3>虑中。&lt;/b&gt;<br>&nbsp;&nbsp; * @param files 需要修改最后访问时间的文件数组。<br>&nbsp;&nbsp; * @since&nbsp; 0.1<br>&nbsp;&nbsp; */<br>&nbsp; public static void touch(File[] files) {<br>&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; files.length; i++) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; touch(files);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp; }</font> </p>
<p><font size=3>&nbsp; /**<br>&nbsp;&nbsp; * 修改文件的最后访问时间。<br>&nbsp;&nbsp; * 如果文件不存在则创建该文件。<br>&nbsp;&nbsp; * &lt;b&gt;目前这个方法的行为方式还不稳定，主要是方法有些信息输出，这些信息输出是否保留还在考</font> </p>
<p><font size=3>虑中。&lt;/b&gt;<br>&nbsp;&nbsp; * @param fileNames 需要修改最后访问时间的文件名数组。<br>&nbsp;&nbsp; * @since&nbsp; 0.1<br>&nbsp;&nbsp; */<br>&nbsp; public static void touch(String[] fileNames) {<br>&nbsp;&nbsp;&nbsp; File[] files = new File[fileNames.length];<br>&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; fileNames.length; i++) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; files = new File(fileNames);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; touch(files);<br>&nbsp; }</font> </p>
<p><font size=3>&nbsp; /**<br>&nbsp;&nbsp; * 判断指定的文件是否存在。<br>&nbsp;&nbsp; * @param fileName 要判断的文件的文件名<br>&nbsp;&nbsp; * @return 存在时返回true，否则返回false。<br>&nbsp;&nbsp; * @since&nbsp; 0.1<br>&nbsp;&nbsp; */<br>&nbsp; public static boolean isFileExist(String fileName) {<br>&nbsp;&nbsp;&nbsp; return new File(fileName).isFile();<br>&nbsp; }</font> </p>
<p><font size=3>&nbsp; /**<br>&nbsp;&nbsp; * 创建指定的目录。<br>&nbsp;&nbsp; * 如果指定的目录的父目录不存在则创建其目录书上所有需要的父目录。<br>&nbsp;&nbsp; * &lt;b&gt;注意：可能会在返回false的时候创建部分父目录。&lt;/b&gt;<br>&nbsp;&nbsp; * @param file 要创建的目录<br>&nbsp;&nbsp; * @return 完全创建成功时返回true，否则返回false。<br>&nbsp;&nbsp; * @since&nbsp; 0.1<br>&nbsp;&nbsp; */<br>&nbsp; public static boolean makeDirectory(File file) {<br>&nbsp;&nbsp;&nbsp; File parent = file.getParentFile();<br>&nbsp;&nbsp;&nbsp; if (parent != null) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return parent.mkdirs();<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; return false;<br>&nbsp; }</font> </p>
<p><font size=3>&nbsp; /**<br>&nbsp;&nbsp; * 创建指定的目录。<br>&nbsp;&nbsp; * 如果指定的目录的父目录不存在则创建其目录书上所有需要的父目录。<br>&nbsp;&nbsp; * &lt;b&gt;注意：可能会在返回false的时候创建部分父目录。&lt;/b&gt;<br>&nbsp;&nbsp; * @param fileName 要创建的目录的目录名<br>&nbsp;&nbsp; * @return 完全创建成功时返回true，否则返回false。<br>&nbsp;&nbsp; * @since&nbsp; 0.1<br>&nbsp;&nbsp; */<br>&nbsp; public static boolean makeDirectory(String fileName) {<br>&nbsp;&nbsp;&nbsp; File file = new File(fileName);<br>&nbsp;&nbsp;&nbsp; return makeDirectory(file);<br>&nbsp; }</font> </p>
<p><font size=3>&nbsp; /**<br>&nbsp;&nbsp; * 清空指定目录中的文件。<br>&nbsp;&nbsp; * 这个方法将尽可能删除所有的文件，但是只要有一个文件没有被删除都会返回false。<br>&nbsp;&nbsp; * 另外这个方法不会迭代删除，即不会删除子目录及其内容。<br>&nbsp;&nbsp; * @param directory 要清空的目录<br>&nbsp;&nbsp; * @return 目录下的所有文件都被成功删除时返回true，否则返回false.<br>&nbsp;&nbsp; * @since&nbsp; 0.1<br>&nbsp;&nbsp; */<br>&nbsp; public static boolean emptyDirectory(File directory) {<br>&nbsp;&nbsp;&nbsp; boolean result = false;<br>&nbsp;&nbsp;&nbsp; File[] entries = directory.listFiles();<br>&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; entries.length; i++) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!entries.delete()) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result = false;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; return true;<br>&nbsp; }</font> </p>
<p><font size=3>&nbsp; /**<br>&nbsp;&nbsp; * 清空指定目录中的文件。<br>&nbsp;&nbsp; * 这个方法将尽可能删除所有的文件，但是只要有一个文件没有被删除都会返回false。<br>&nbsp;&nbsp; * 另外这个方法不会迭代删除，即不会删除子目录及其内容。<br>&nbsp;&nbsp; * @param directoryName 要清空的目录的目录名<br>&nbsp;&nbsp; * @return 目录下的所有文件都被成功删除时返回true，否则返回false。<br>&nbsp;&nbsp; * @since&nbsp; 0.1<br>&nbsp;&nbsp; */<br>&nbsp; public static boolean emptyDirectory(String directoryName) {<br>&nbsp;&nbsp;&nbsp; File dir = new File(directoryName);<br>&nbsp;&nbsp;&nbsp; return emptyDirectory(dir);<br>&nbsp; }</font> </p>
<p><font size=3>&nbsp; /**<br>&nbsp;&nbsp; * 删除指定目录及其中的所有内容。<br>&nbsp;&nbsp; * @param dirName 要删除的目录的目录名<br>&nbsp;&nbsp; * @return 删除成功时返回true，否则返回false。<br>&nbsp;&nbsp; * @since&nbsp; 0.1<br>&nbsp;&nbsp; */<br>&nbsp; public static boolean deleteDirectory(String dirName) {<br>&nbsp;&nbsp;&nbsp; return deleteDirectory(new File(dirName));<br>&nbsp; }</font> </p>
<p><font size=3>&nbsp; /**<br>&nbsp;&nbsp; * 删除指定目录及其中的所有内容。<br>&nbsp;&nbsp; * @param dir 要删除的目录<br>&nbsp;&nbsp; * @return 删除成功时返回true，否则返回false。<br>&nbsp;&nbsp; * @since&nbsp; 0.1<br>&nbsp;&nbsp; */<br>&nbsp; public static boolean deleteDirectory(File dir) {<br>&nbsp;&nbsp;&nbsp; if ( (dir == null) || !dir.isDirectory()) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new IllegalArgumentException("Argument " + dir +<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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; " is not a directory. ");<br>&nbsp;&nbsp;&nbsp; }</font> </p>
<p><font size=3>&nbsp;&nbsp;&nbsp; File[] entries = dir.listFiles();<br>&nbsp;&nbsp;&nbsp; int sz = entries.length;</font> </p>
<p><font size=3>&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; sz; i++) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (entries.isDirectory()) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!deleteDirectory(entries)) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!entries.delete()) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }</font> </p>
<p><font size=3>&nbsp;&nbsp;&nbsp; if (!dir.delete()) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; return true;<br>&nbsp; }</font> </p>
<p><br><font size=3>&nbsp; /**<br>&nbsp;&nbsp; * 返回文件的URL地址。<br>&nbsp;&nbsp; * @param file 文件<br>&nbsp;&nbsp; * @return 文件对应的的URL地址<br>&nbsp;&nbsp; * @throws MalformedURLException<br>&nbsp;&nbsp; * @since&nbsp; 0.4<br>&nbsp;&nbsp; * @deprecated 在实现的时候没有注意到File类本身带一个toURL方法将文件路径转换为URL。<br>&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 请使用File.toURL方法。<br>&nbsp;&nbsp; */<br>&nbsp; public static URL getURL(File file) throws MalformedURLException {<br>&nbsp;&nbsp;&nbsp; String fileURL = "file:/" + file.getAbsolutePath();<br>&nbsp;&nbsp;&nbsp; URL url = new URL(fileURL);<br>&nbsp;&nbsp;&nbsp; return url;<br>&nbsp; }</font> </p>
<p><font size=3>&nbsp; /**<br>&nbsp;&nbsp; * 从文件路径得到文件名。<br>&nbsp;&nbsp; * @param filePath 文件的路径，可以是相对路径也可以是绝对路径<br>&nbsp;&nbsp; * @return 对应的文件名<br>&nbsp;&nbsp; * @since&nbsp; 0.4<br>&nbsp;&nbsp; */<br>&nbsp; public static String getFileName(String filePath) {<br>&nbsp;&nbsp;&nbsp; File file = new File(filePath);<br>&nbsp;&nbsp;&nbsp; return file.getName();<br>&nbsp; }</font> </p>
<p><font size=3>&nbsp; /**<br>&nbsp;&nbsp; * 从文件名得到文件绝对路径。<br>&nbsp;&nbsp; * @param fileName 文件名<br>&nbsp;&nbsp; * @return 对应的文件路径<br>&nbsp;&nbsp; * @since&nbsp; 0.4<br>&nbsp;&nbsp; */<br>&nbsp; public static String getFilePath(String fileName) {<br>&nbsp;&nbsp;&nbsp; File file = new File(fileName);<br>&nbsp;&nbsp;&nbsp; return file.getAbsolutePath();<br>&nbsp; }</font> </p>
<p><font size=3>&nbsp; /**<br>&nbsp;&nbsp; * 将DOS/Windows格式的路径转换为UNIX/Linux格式的路径。<br>&nbsp;&nbsp; * 其实就是将路径中的"\"全部换为"/"，因为在某些情况下我们转换为这种方式比较方便，<br>&nbsp;&nbsp; * 某中程度上说"/"比"\"更适合作为路径分隔符，而且DOS/Windows也将它当作路径分隔符。<br>&nbsp;&nbsp; * @param filePath 转换前的路径<br>&nbsp;&nbsp; * @return 转换后的路径<br>&nbsp;&nbsp; * @since&nbsp; 0.4<br>&nbsp;&nbsp; */<br>&nbsp; public static String toUNIXpath(String filePath) {<br>&nbsp;&nbsp;&nbsp; return filePath.replace('\\', '/');<br>&nbsp; }</font> </p>
<p><font size=3>&nbsp; /**<br>&nbsp;&nbsp; * 从文件名得到UNIX风格的文件绝对路径。<br>&nbsp;&nbsp; * @param fileName 文件名<br>&nbsp;&nbsp; * @return 对应的UNIX风格的文件路径<br>&nbsp;&nbsp; * @since&nbsp; 0.4<br>&nbsp;&nbsp; * @see #toUNIXpath(String filePath) toUNIXpath<br>&nbsp;&nbsp; */<br>&nbsp; public static String getUNIXfilePath(String fileName) {<br>&nbsp;&nbsp;&nbsp; File file = new File(fileName);<br>&nbsp;&nbsp;&nbsp; return toUNIXpath(file.getAbsolutePath());<br>&nbsp; }</font> </p>
<p><font size=3>&nbsp; /**<br>&nbsp;&nbsp; * 得到文件的类型。<br>&nbsp;&nbsp; * 实际上就是得到文件名中最后一个&#8220;.&#8221;后面的部分。<br>&nbsp;&nbsp; * @param fileName 文件名<br>&nbsp;&nbsp; * @return 文件名中的类型部分<br>&nbsp;&nbsp; * @since&nbsp; 0.5<br>&nbsp;&nbsp; */<br>&nbsp; public static String getTypePart(String fileName) {<br>&nbsp;&nbsp;&nbsp; int point = fileName.lastIndexOf('.');<br>&nbsp;&nbsp;&nbsp; int length = fileName.length();<br>&nbsp;&nbsp;&nbsp; if (point == -1 || point == length - 1) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return "";<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; else {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return fileName.substring(point + 1, length);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp; }</font> </p>
<p><font size=3>&nbsp; /**<br>&nbsp;&nbsp; * 得到文件的类型。<br>&nbsp;&nbsp; * 实际上就是得到文件名中最后一个&#8220;.&#8221;后面的部分。<br>&nbsp;&nbsp; * @param file 文件<br>&nbsp;&nbsp; * @return 文件名中的类型部分<br>&nbsp;&nbsp; * @since&nbsp; 0.5<br>&nbsp;&nbsp; */<br>&nbsp; public static String getFileType(File file) {<br>&nbsp;&nbsp;&nbsp; return getTypePart(file.getName());<br>&nbsp; }</font> </p>
<p><font size=3>&nbsp; /**<br>&nbsp;&nbsp; * 得到文件的名字部分。<br>&nbsp;&nbsp; * 实际上就是路径中的最后一个路径分隔符后的部分。<br>&nbsp;&nbsp; * @param fileName 文件名<br>&nbsp;&nbsp; * @return 文件名中的名字部分<br>&nbsp;&nbsp; * @since&nbsp; 0.5<br>&nbsp;&nbsp; */<br>&nbsp; public static String getNamePart(String fileName) {<br>&nbsp;&nbsp;&nbsp; int point = getPathLsatIndex(fileName);<br>&nbsp;&nbsp;&nbsp; int length = fileName.length();<br>&nbsp;&nbsp;&nbsp; if (point == -1) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return fileName;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; else if (point == length - 1) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int secondPoint = getPathLsatIndex(fileName, point - 1);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (secondPoint == -1) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (length == 1) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return fileName;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return fileName.substring(0, point);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return fileName.substring(secondPoint + 1, point);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; else {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return fileName.substring(point + 1);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp; }</font> </p>
<p><font size=3>&nbsp; /**<br>&nbsp;&nbsp; * 得到文件名中的父路径部分。<br>&nbsp;&nbsp; * 对两种路径分隔符都有效。<br>&nbsp;&nbsp; * 不存在时返回""。<br>&nbsp;&nbsp; * 如果文件名是以路径分隔符结尾的则不考虑该分隔符，例如"/path/"返回""。<br>&nbsp;&nbsp; * @param fileName 文件名<br>&nbsp;&nbsp; * @return 父路径，不存在或者已经是父目录时返回""<br>&nbsp;&nbsp; * @since&nbsp; 0.5<br>&nbsp;&nbsp; */<br>&nbsp; public static String getPathPart(String fileName) {<br>&nbsp;&nbsp;&nbsp; int point = getPathLsatIndex(fileName);<br>&nbsp;&nbsp;&nbsp; int length = fileName.length();<br>&nbsp;&nbsp;&nbsp; if (point == -1) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return "";<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; else if (point == length - 1) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int secondPoint = getPathLsatIndex(fileName, point - 1);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (secondPoint == -1) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return "";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return fileName.substring(0, secondPoint);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; else {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return fileName.substring(0, point);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp; }</font> </p>
<p><font size=3>&nbsp; /**<br>&nbsp;&nbsp; * 得到路径分隔符在文件路径中首次出现的位置。<br>&nbsp;&nbsp; * 对于DOS或者UNIX风格的分隔符都可以。<br>&nbsp;&nbsp; * @param fileName 文件路径<br>&nbsp;&nbsp; * @return 路径分隔符在路径中首次出现的位置，没有出现时返回-1。<br>&nbsp;&nbsp; * @since&nbsp; 0.5<br>&nbsp;&nbsp; */<br>&nbsp; public static int getPathIndex(String fileName) {<br>&nbsp;&nbsp;&nbsp; int point = fileName.indexOf('/');<br>&nbsp;&nbsp;&nbsp; if (point == -1) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; point = fileName.indexOf('\\');<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; return point;<br>&nbsp; }</font> </p>
<p><font size=3>&nbsp; /**<br>&nbsp;&nbsp; * 得到路径分隔符在文件路径中指定位置后首次出现的位置。<br>&nbsp;&nbsp; * 对于DOS或者UNIX风格的分隔符都可以。<br>&nbsp;&nbsp; * @param fileName 文件路径<br>&nbsp;&nbsp; * @param fromIndex 开始查找的位置<br>&nbsp;&nbsp; * @return 路径分隔符在路径中指定位置后首次出现的位置，没有出现时返回-1。<br>&nbsp;&nbsp; * @since&nbsp; 0.5<br>&nbsp;&nbsp; */<br>&nbsp; public static int getPathIndex(String fileName, int fromIndex) {<br>&nbsp;&nbsp;&nbsp; int point = fileName.indexOf('/', fromIndex);<br>&nbsp;&nbsp;&nbsp; if (point == -1) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; point = fileName.indexOf('\\', fromIndex);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; return point;<br>&nbsp; }</font> </p>
<p><font size=3>&nbsp; /**<br>&nbsp;&nbsp; * 得到路径分隔符在文件路径中最后出现的位置。<br>&nbsp;&nbsp; * 对于DOS或者UNIX风格的分隔符都可以。<br>&nbsp;&nbsp; * @param fileName 文件路径<br>&nbsp;&nbsp; * @return 路径分隔符在路径中最后出现的位置，没有出现时返回-1。<br>&nbsp;&nbsp; * @since&nbsp; 0.5<br>&nbsp;&nbsp; */<br>&nbsp; public static int getPathLsatIndex(String fileName) {<br>&nbsp;&nbsp;&nbsp; int point = fileName.lastIndexOf('/');<br>&nbsp;&nbsp;&nbsp; if (point == -1) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; point = fileName.lastIndexOf('\\');<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; return point;<br>&nbsp; }</font> </p>
<p><font size=3>&nbsp; /**<br>&nbsp;&nbsp; * 得到路径分隔符在文件路径中指定位置前最后出现的位置。<br>&nbsp;&nbsp; * 对于DOS或者UNIX风格的分隔符都可以。<br>&nbsp;&nbsp; * @param fileName 文件路径<br>&nbsp;&nbsp; * @param fromIndex 开始查找的位置<br>&nbsp;&nbsp; * @return 路径分隔符在路径中指定位置前最后出现的位置，没有出现时返回-1。<br>&nbsp;&nbsp; * @since&nbsp; 0.5<br>&nbsp;&nbsp; */<br>&nbsp; public static int getPathLsatIndex(String fileName, int fromIndex) {<br>&nbsp;&nbsp;&nbsp; int point = fileName.lastIndexOf('/', fromIndex);<br>&nbsp;&nbsp;&nbsp; if (point == -1) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; point = fileName.lastIndexOf('\\', fromIndex);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; return point;<br>&nbsp; }</font> </p>
<p><font size=3>&nbsp; /**<br>&nbsp;&nbsp; * 将文件名中的类型部分去掉。<br>&nbsp;&nbsp; * @param filename 文件名<br>&nbsp;&nbsp; * @return 去掉类型部分的结果<br>&nbsp;&nbsp; * @since&nbsp; 0.5<br>&nbsp;&nbsp; */<br>&nbsp; public static String trimType(String filename) {<br>&nbsp;&nbsp;&nbsp; int index = filename.lastIndexOf(".");<br>&nbsp;&nbsp;&nbsp; if (index != -1) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return filename.substring(0, index);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; else {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return filename;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp; }<br>&nbsp; /**<br>&nbsp;&nbsp; * 得到相对路径。<br>&nbsp;&nbsp; * 文件名不是目录名的子节点时返回文件名。<br>&nbsp;&nbsp; * @param pathName 目录名<br>&nbsp;&nbsp; * @param fileName 文件名<br>&nbsp;&nbsp; * @return 得到文件名相对于目录名的相对路径，目录下不存在该文件时返回文件名<br>&nbsp;&nbsp; * @since&nbsp; 0.5<br>&nbsp;&nbsp; */<br>&nbsp; public static String getSubpath(String pathName,String fileName) {<br>&nbsp;&nbsp;&nbsp; int index = fileName.indexOf(pathName);<br>&nbsp;&nbsp;&nbsp; if (index != -1) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return fileName.substring(index + pathName.length() + 1);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; else {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return fileName;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp; }</font> </p>
<p><font size=3>}<br>&nbsp;4.遗留问题</font> </p>
<p><font size=3>目前new FileInputStream()只会使用绝对路径，相对没用过，因为要相对于web服务器地址，比较麻烦</font> </p>
<p><font size=3>还不如写个配置文件来的快哪</font> </p>
<p><font size=3>5.按Java文件类型分类读取配置文件</font> </p>
<div class=storycontent>
<p><font size=3>配置文件是应用系统中不可缺少的，可以增加程序的灵活性。java.util.Properties是从jdk1.2就有的类，一直到现在都支持load ()方法，jdk1.4以后save(output,string) -&gt;store(output,string)。如果只是单纯的读，根本不存在烦恼的问题。web层可以通过 Thread.currentThread().getContextClassLoader().<br>getResourceAsStream("xx.properties") 获取；Application可以通过new FileInputStream("xx.properties");直接在classes一级获取。关键是有时我们需要通过web修改配置文件，我们不能将路径写死了。经过测试觉得有以下心得：</font> </p>
<p><font size=3>1.servlet中读写。如果运用Struts 或者Servlet可以直接在初始化参数中配置，调用时根据servlet的getRealPath("/")获取真实路径，再根据String file = this.servlet.getInitParameter("abc");获取相对的WEB-INF的相对路径。<br>例：<br>InputStream input = Thread.currentThread().getContextClassLoader().<br>getResourceAsStream("abc.properties");<br>Properties prop = new Properties();<br>prop.load(input);<br>input.close();<br>OutputStream out = new FileOutputStream(path);<br>prop.setProperty("abc", &#8220;test");<br>prop.store(out, &#8220;&#8211;test&#8211;");<br>out.close();</font> </p>
<p><font size=3>2.直接在jsp中操作，通过jsp内置对象获取可操作的绝对地址。<br>例：<br>// jsp页面<br>String path = pageContext.getServletContext().getRealPath("/");<br>String realPath = path+"/WEB-INF/classes/abc.properties";</font> </p>
<p><font size=3>//java 程序<br>InputStream in = getClass().getClassLoader().getResourceAsStream("abc.properties"); // abc.properties放在webroot/WEB-INF/classes/目录下<br>prop.load(in);<br>in.close();</font> </p>
<p><font size=3>OutputStream out = new FileOutputStream(path); // path为通过页面传入的路径<br>prop.setProperty("abc", &#8220;abcccccc");<br>prop.store(out, &#8220;&#8211;test&#8211;");<br>out.close();</font> </p>
<p><font size=3>3.只通过Java程序操作资源文件<br>InputStream in = new FileInputStream("abc.properties"); // 放在classes同级</font> </p>
<p><font size=3>OutputStream out = new FileOutputStream("abc.properties");</font> </p>
</div>
<img src ="http://www.blogjava.net/masen/aggbug/108656.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/masen/" target="_blank">Masen</a> 2007-04-05 11:47 <a href="http://www.blogjava.net/masen/articles/108656.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts多模块开发</title><link>http://www.blogjava.net/masen/articles/106277.html</link><dc:creator>Masen</dc:creator><author>Masen</author><pubDate>Sun, 25 Mar 2007 14:20:00 GMT</pubDate><guid>http://www.blogjava.net/masen/articles/106277.html</guid><wfw:comment>http://www.blogjava.net/masen/comments/106277.html</wfw:comment><comments>http://www.blogjava.net/masen/articles/106277.html#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://www.blogjava.net/masen/comments/commentRss/106277.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/masen/services/trackbacks/106277.html</trackback:ping><description><![CDATA[
		<p>在基于struts的WEB应用的开发中,使用多模块开发是十分必要的,总结了一下如下:</p>
		<p>Struts 的配置文件struts-config.xml 是Struts 框架最重要的资源之一，并且是需要频繁改动的。如果并行开发的各个团队都是用这一个配置文件，势必造成访问冲突。Strus 框架的模块化机制就是专门应对这种情况的。</p>
		<p>Struts 从1.1 版本开始增加了模块化支持，并且一直在强化对模块化的支持。不同的应用模块可以拥有各自的struts-config 配置文件、消息资源、Validator 框架配置文件。不同的模块可以协同开发，互不影响。</p>
		<p>Struts 应用配置为多模块应用，需要如下三个步骤：</p>
		<p>为每个模块分别建立一个struts配置文件； <br />通知模块控制器； <br />使用特定的Action在模块间跳转。 <br />一 给各模块命名:</p>
		<p>struts默认的配置文件名是struts-config.xml,给其它模块配置文件命名struts-config-***.xml.比如登录模块需要一个单独的模块可以命名为struts-config-login.xml;</p>
		<p>二 通知模块控制器:</p>
		<p>在web.xml中加入如下代码:</p>
		<p>&lt;init-param&gt;     <br />      &lt;param-name&gt;config&lt;/param-name&gt;     <br />      &lt;param-value&gt;/WEB-INF/conf/struts-config.xml&lt;/param-value&gt;     <br />&lt;/init-param&gt;     <br />&lt;init-param&gt;     <br />      &lt;param-name&gt;config/login&lt;/param-name&gt;     <br />      &lt;param-value&gt;/WEB-INF/conf/login/struts-config-login.xml&lt;/param-value&gt;     <br />&lt;/init-param&gt;    </p>
		<p>配置文件对应的ActionServlet 初始化参数名为config。对于其他模块，ActionServlet 初始化参数的命名原则是“config/模块名”。如上面的代码示例中，login 模块的配置文件对应的初始化参数为config/login。其中前缀“config/”是不能缺少的，后面跟模块名。在Struts 控制器中，是通过模块名来区分不同模块的。在资源访问中，也是一模块名作为前缀来区分对不同模块的访问。如以“/login”开头的路径会告诉控制器所要访问的将是login 模块的资源。</p>
		<p>三 实现模块间跳转:</p>
		<p>(1)用SwitchAction,主要用于实现页面的跳转</p>
		<p>(2)全局转发和局部转发,用于实现模块间的跳转</p>
		<p>(3)采用html:link标签</p>
		<p>多模块开发示例：（Eclipse3.2+MyEclipse5.0） <br />1．新建一个Web Project <br />2．添加Struts 1.2 支持 <br />3．在根目录（WebRoot）下新建index.jsp页面 <br />4．在WebRoot目录下新建一个模块目录“ModuleA”。 <br />5．新建一个struts 1.2 module，名为“ModuleA”。 <br />6．测试直接链接到其他模块的jsp页面（注意不能直接链接到其他模块的与Action、ActionForm相关联的页面）：</p>
		<p>在根目录的index.jsp页面中添加如下代码：</p>
		<p>&lt;html:link module="/ModuleA" page="/index.jsp"&gt;1.链接到其他模块（ModuleA）直接链接到页面&lt;/html:link&gt;&lt;br&gt;适用于没有和Action，ActionForm关联的纯JSP页面&lt;br&gt;&lt;p&gt;</p>
		<p>在ModuleA目录下新建index.jsp页面，完成后测试成功。 <br /><br />7．测试直接链接到其他模块的jsp页面（直接链接到其他模块的与Action、ActionForm相关联的页面，应该不能成功）： <br />首先配置struts-config-ModuleA.xml文件： <br />新建一个Form、Action and JSP，用例中填写user，添加两个属性：name，password。 <br />在JSP选项卡中填写“/ModuleA/login.jsp”，点击下一步，在Path中填写“/login”，在forward选项卡中添加一个forward，name为“OK”，Path为“/welcome.jsp”，点击完成。 <br />在ModuleA目录下新建wellcome.jsp文件，在源码中加入如下代码： <br />&lt;bean:write name=”userForm” property=”name” /&gt;.在UserAction.java源码中填写如下代码:return mapping.findForward(“OK”)。 <br />在根目录下的index.jsp源码中添加如下代码： <br />&lt;html:link module="/ModuleA" page="/login.jsp"&gt;2.链接到其他模块（ModuleA）试图连接到和Action，ActionForm关联的页面&lt;/html:link&gt;&lt;br&gt;不能直接这样链接，会报Cannot retrieve mapping for action /xxx异常，因为此时还是检查struts-config.xml&lt;br&gt;&lt;p&gt; <br />测试后果然异常。 <br />正确做法如下： <br />在struts-config-ModuleA.xml文件中添加一个Action，在用例中填写“toLoginPage”，在forward选项卡中添加一个forward，name为“toLoginPage”，Path为“/login.jsp”。 <br />修改ToLoginPage.java的源码为：return mapping.findForward(“toLoginPage”);。 <br />在根目录下的index.jsp源码中添加如下代码： <br />&lt;html:link module="/ModuleA" page="/toLoginPage.do"&gt;3.链接到其他模块（ModuleA）的xxxx.do，连接到和Action，ActionForm关联的页面&lt;/html:link&gt;&lt;br&gt;正确做法，是对2链接形式的更正，应该链接到ModuleA的一个Action，由该Action的forward转发到login.jsp页面&lt;br&gt;&lt;p&gt; <br />经测试成功。</p>
		<p>8．测试跨模块表单提交（从主模块提交表单到ModuleA模块）： <br />在struts-config.xml（主模块）中新建Form、Action and JSP，用例中输入“reg”，增加两个属性：sex、age，点击下一步，在Path中填写“/userReg”，Action Impl中选择Use existing Action class，使用SwitchAction，直接finish掉。添加根目录下的indexs.jsp文件源码如下：</p>
		<p>4.提交表单到其他模块：&lt;br&gt; <br />&lt;html:form action="/userReg?prefix=/ModuleA&amp;page=/regOK.jsp"&gt; <br />sex : &lt;html:text property="sex"/&gt;&lt;html:errors property="sex"/&gt;&lt;br/&gt; <br />age : &lt;html:text property="age"/&gt;&lt;html:errors property="age"/&gt;&lt;br/&gt; <br />&lt;html:submit/&gt;&lt;html:cancel/&gt; <br />&lt;/html:form&gt;&lt;br&gt;&lt;p&gt;。</p>
		<p>在ModuleA文件夹下新建regOK.jsp文件，在regOK.jsp文件源码中写入如下语句： <br />regOK,your sex is:&lt;bean:write name="regForm" property="sex"/&gt; age is:&lt;bean:write name="regForm" property="age"/&gt; <br />经测试成功。</p>
		<p>9．测试跨模块表单提交（从ModuleA模块提交表单到ModuleB模块）： <br />新建struts1.2模块，叫“ModuleB”，在WebRoot目录下新建文件夹“ModuleB”，配置struts-config-ModuleB.xml文件： <br />新建Form、Action and JSP，在用例中输入“employee”，增加两个属性：empName、depName，在JSP选项卡中填写“/ModuleA/empInfo.jsp”，点击下一步，Path中填写“/employee”，在Action Impl中选择Use existing Action class，使用SwitchAction，直接finish掉。 <br />修改empInfo.jsp文件源码：&lt;html:form action="/employee?prefix=/ModuleB&amp;page=/showEmp.jsp"&gt;…。 <br />在ModuleB文件夹中新建showEmp.jsp文件，修改showemp.jsp源码为：&lt;bean:write name="employeeForm" property="empName"/&gt;。 <br />在struts-config-ModuleA.xml文件中，增加一个Action，在用例中输入“empInfo”，增加一个forward，name为“/empInfo.jsp”。在根目录下的index.jsp文件中增加如下内容： <br />5.提交表单到其他模块（子模块到子模块）：&lt;br&gt; <br />&lt;html:link module="/ModuleA" page="/empInfo.do"&gt;链接到模块（ModuleB）的empInfo.do&lt;/html:link&gt;&lt;br&gt;链接到ModuleA的一个Action，由该Action的forward转发到empInfo.jsp页面&lt;br&gt;&lt;p&gt; <br />最后修改EmpInfoAction.java源码：return mapping.findForward("empOK"); <br />经测试成功。</p>
<img src ="http://www.blogjava.net/masen/aggbug/106277.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/masen/" target="_blank">Masen</a> 2007-03-25 22:20 <a href="http://www.blogjava.net/masen/articles/106277.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts中的3种Action类</title><link>http://www.blogjava.net/masen/articles/105861.html</link><dc:creator>Masen</dc:creator><author>Masen</author><pubDate>Fri, 23 Mar 2007 07:58:00 GMT</pubDate><guid>http://www.blogjava.net/masen/articles/105861.html</guid><wfw:comment>http://www.blogjava.net/masen/comments/105861.html</wfw:comment><comments>http://www.blogjava.net/masen/articles/105861.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/masen/comments/commentRss/105861.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/masen/services/trackbacks/105861.html</trackback:ping><description><![CDATA[
		<p>DispatchAction, LookupDispatchAction, MappingDispatchAction</p>
		<p>
				<br />1) DispatchAction就是在struts-config中用parameter参数配置一个表单字段名,这个字段的值就是最终替代execute被调用的方法. 例如parameter="method"而request.getParameter("method")="save"，其中"save"就是MethodName。struts的请求将根据parameter被分发到"save"或者"edit"或者什么。但是有一点，save()或者edit()等方法的声明和execute必须一模一样。同时：删除以前的execute(----)方法，如:<br />-------<br />-------<br />public class UserAction extends DispatchAction </p>
		<p>{ </p>
		<p>    public ActionForward addUser (ActionMapping mapping,ActionForm form, </p>
		<p>            HttpServletRequest request,HttpServletResponse response) throws Exception </p>
		<p>    { </p>
		<p>             // 增加用户业务的逻辑 </p>
		<p>            return mapping.findForward(Constant. FORWARD_ADD ); </p>
		<p>    } </p>
		<p>    </p>
		<p>    public ActionForward delUser(ActionMapping mapping,ActionForm form, </p>
		<p>            HttpServletRequest request,HttpServletResponse response) throws Exception </p>
		<p>    { </p>
		<p>             // 删除用户业务的逻辑 </p>
		<p>            return mapping.findForward(Constant. FORWARD_SUCCESS ); </p>
		<p>    } </p>
		<p>
		</p>
		<p>    public ActionForward updateUser(ActionMapping mapping,ActionForm form, </p>
		<p>            HttpServletRequest request,HttpServletResponse response) throws Exception </p>
		<p>    { </p>
		<p>             // 更新用户业务的逻辑 </p>
		<p>            return mapping.findForward(Constant. FORWARD_SUCCESS ); </p>
		<p>    } </p>
		<p>} </p>
		<p> </p>
		<p>2) LookupDispatchAction继承DispatchAction, 用于对同一个页面上的多个submit按钮进行不同的响应。其原理是，首先用MessageResource将按钮的文本和ResKey相关联，例如button.save=save；然后再复写getKeyMethodMap(), 将ResKey和MethodName对应起来, 例如map.put("button.save", "save"); 其配置方法和DispatchAction是一样的,  parameter属性为：method 如：<br />&lt;html:submit property="method"&gt;<br />&lt;bean:message key="button.save"/&gt;<br />&lt;/html:submit&gt;<br />&lt;html:submit property="method"&gt;<br />&lt;bean:message key="button.delete"/&gt;<br />&lt;/html:submit&gt;<br />注意：此Action一定要有对应的FormBean， 就是说一定要有name属性， 同时要删除此类的execute(-----)方法<br />资源文件如:<br />button.save=save<br />button.delete=delete</p>
		<p>3) MappingDispatchAction是1.2新加的, 也继承自DispatchAction. 它实现的功能和上面两个区别较大, 是通过struts-config.xml将多个action-mapping映射到同一个Action类的不同方法上, 典型的配置就是:<br />&lt;action-mappings&gt;<br />&lt;action path="/saveUser" type="logic.UserAction" parameter="save"&gt;&lt;/action&gt;<br />&lt;action path="/editUser" type="logic.UserAction" parameter="edit"&gt;&lt;/action&gt;<br />&lt;/action-mappings&gt;<br />然后UserAction继承MappingDispatchAction，其中有：<br />public ActionForward save(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception <br />public ActionForward edit(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception <br />等方法<br /></p>
<img src ="http://www.blogjava.net/masen/aggbug/105861.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/masen/" target="_blank">Masen</a> 2007-03-23 15:58 <a href="http://www.blogjava.net/masen/articles/105861.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>