X-Spirit的陋室铭

生活有的时候面临许多选择,这些选择让人困惑。 生活有的时候没有任何选择,这个时候让人压抑。 但无论生活有没有给你选择,你只能做一件事情: 排除困难,勇往直前!

2008年3月19日星期三

JS正则表达式详解

JS的正则表达式

//校验是否全由数字组成
[code] function isDigit(s) { var patrn=/^[0-9]{1,20}$/; if (!patrn.exec(s)) return false return true } [/code]

//校验登录名:只能输入5-20个以字母开头、可带数字、“_”、“.”的字串
[code] function isRegisterUserName(s) { var patrn=/^[a-zA-Z]{1}([a-zA-Z0-9]|[._]){4,19}$/; if (!patrn.exec(s)) return false return true } [/code]

//校验用户姓名:只能输入1-30个以字母开头的字串
[code] function isTrueName(s) { var patrn=/^[a-zA-Z]{1,30}$/; if (!patrn.exec(s)) return false return true } }} //校验密码:只能输入6-20个字母、数字、下划线 [code] function isPasswd(s) { var patrn=/^(\w){6,20}$/; if (!patrn.exec(s)) return false return true } [/code]

//校验普通电话、传真号码:可以“+”开头,除数字外,可含有“-”
[code] function isTel(s) { //var patrn=/^[+]{0,1}(\d){1,3}[ ]?([-]?(\d){1,12})+$/; var patrn=/^[+]{0,1}(\d){1,3}[ ]?([-]?((\d)|[ ]){1,12})+$/; if (!patrn.exec(s)) return false return true } [/code]

//校验手机号码:必须以数字开头,除数字外,可含有“-”
[code] function isMobil(s) { var patrn=/^[+]{0,1}(\d){1,3}[ ]?([-]?((\d)|[ ]){1,12})+$/; if (!patrn.exec(s)) return false return true } [/code]

//校验邮政编码
[code] function isPostalCode(s) { //var patrn=/^[a-zA-Z0-9]{3,12}$/; var patrn=/^[a-zA-Z0-9 ]{3,12}$/; if (!patrn.exec(s)) return false return true } [/code]

//校验搜索关键字
[code] function isSearch(s) { var patrn=/^[^`~!@#$%^&*()+=|\\\][\]\{\}:;'\,.<>/?]{1}[^`~!@$%^&()+=|\\\] [\]\{\}:;'\,.<>?]{0,19}$/; if (!patrn.exec(s)) return false return true } function isIP(s) //by zergling { var patrn=/^[0-9.]{1,20}$/; if (!patrn.exec(s)) return false return true } [/code]

正则表达式
[code] "^\\d+$"  //非负整数(正整数 + 0) "^[0-9]*[1-9][0-9]*$"  //正整数 "^((-\\d+)|(0+))$"  //非正整数(负整数 + 0) "^-[0-9]*[1-9][0-9]*$"  //负整数 "^-?\\d+$"    //整数 "^\\d+(\\.\\d+)?$"  //非负浮点数(正浮点数 + 0) "^(([0-9]+\\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\\.[0-9]+)|([0-9]*[1-9][0-9]*))$"  //正浮点数 "^((-\\d+(\\.\\d+)?)|(0+(\\.0+)?))$"  //非正浮点数(负浮点数 + 0) "^(-(([0-9]+\\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\\.[0-9]+)|([0-9]*[1-9][0-9]*)))$"  //负浮点数 "^(-?\\d+)(\\.\\d+)?$"  //浮点数 "^[A-Za-z]+$"  //由26个英文字母组成的字符串 "^[A-Z]+$"  //由26个英文字母的大写组成的字符串 "^[a-z]+$"  //由26个英文字母的小写组成的字符串 "^[A-Za-z0-9]+$"  //由数字和26个英文字母组成的字符串 "^\\w+$"  //由数字、26个英文字母或者下划线组成的字符串 "^[\\w-]+(\\.[\\w-]+)*@[\\w-]+(\\.[\\w-]+)+$"    //email地址 "^[a-zA-z]+://(\\w+(-\\w+)*)(\\.(\\w+(-\\w+)*))*(\\?\\S*)?$"  //url "^[A-Za-z0-9_]*$" [/code]

正则表达式使用详解

简介

简单的说,正则表达式是一种可以用于模式匹配和替换的强有力的工具。其作用如下:
测试字符串的某个模式。例如,可以对一个输入字符串进行测试,看在该字符串是否存在一个电话号码模式或一个信用卡号码模式。这称为数据有效性验证。
替换文本。可以在文档中使用一个正则表达式来标识特定文字,然后可以全部将其删除,或者替换为别的文字。
根据模式匹配从字符串中提取一个子字符串。可以用来在文本或输入字段中查找特定文字。

基本语法

在对正则表达式的功能和作用有了初步的了解之后,我们就来具体看一下正则表达式的语法格式。

正则表达式的形式一般如下:  

/love/  其中位于“/”定界符之间的部分就是将要在目标对象中进行匹配的模式。用户只要把希望查找匹配对象的模式内容放入“/”定界符之间即可。为了能够使用户更加灵活的定制模式内容,正则表达式提供了专门的“元字符”。所谓元字符就是指那些在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符)在目标对象中的出现模式。
较为常用的元字符包括: “+”, “*”,以及 “?”。

“+”元字符规定其前导字符必须在目标对象中连续出现一次或多次。

“*”元字符规定其前导字符必须在目标对象中出现零次或连续多次。

“?”元字符规定其前导对象必须在目标对象中连续出现零次或一次。

下面,就让我们来看一下正则表达式元字符的具体应用。

/fo+/  因为上述正则表达式中包含“+”元字符,表示可以与目标对象中的 “fool”, “fo”, 或者 “football”等在字母f后面连续出现一个或多个字母o的字符串相匹配。

/eg*/  因为上述正则表达式中包含“*”元字符,表示可以与目标对象中的 “easy”, “ego”, 或者 “egg”等在字母e后面连续出现零个或多个字母g的字符串相匹配。

/Wil?/  因为上述正则表达式中包含“?”元字符,表示可以与目标对象中的 “Win”, 或者“Wilson”,等在字母i后面连续出现零个或一个字母l的字符串相匹配。

有时候不知道要匹配多少字符。为了能适应这种不确定性,正则表达式支持限定符的概念。这些限定符可以指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。

{n} n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。

{n,} n 是一个非负整数。至少匹配 n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。

{n,m} m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。

除了元字符之外,用户还可以精确指定模式在匹配对象中出现的频率。例如,/jim {2,6}/ 上述正则表达式规定字符m可以在匹配对象中连续出现2-6次,因此,上述正则表达式可以同jimmy或jimmmmmy等字符串相匹配。
在对如何使用正则表达式有了初步了解之后,我们来看一下其它几个重要的元字符的使用方式。
[code] \s:用于匹配单个空格符,包括tab键和换行符; \S:用于匹配除单个空格符之外的所有字符; \d:用于匹配从0到9的数字; \w:用于匹配字母,数字或下划线字符; \W:用于匹配所有与\w不匹配的字符; . :用于匹配除换行符之外的所有字符。 [/code]
(说明:我们可以把\s和\S以及\w和\W看作互为逆运算)
下面,我们就通过实例看一下如何在正则表达式中使用上述元字符。
/\s+/ 上述正则表达式可以用于匹配目标对象中的一个或多个空格字符。
/\d000/ 如果我们手中有一份复杂的财务报表,那么我们可以通过上述正则表达式轻而易举的查找到所有总额达千元的款项。
除了我们以上所介绍的元字符之外,正则表达式中还具有另外一种较为独特的专用字符,即定位符。定位符用于规定匹配模式在目标对象中的出现位置。 较为常用的定位符包括: “^”, “$”, “\b” 以及 “\B”。
[code] “^”定位符规定匹配模式必须出现在目标字符串的开头 “$”定位符规定匹配模式必须出现在目标对象的结尾 “\b”定位符规定匹配模式必须出现在目标字符串的开头或结尾的两个边界之一 “\B”定位符则规定匹配对象必须位于目标字符串的开头和结尾两个边界之内, 即匹配对象既不能作为目标字符串的开头,也不能作为目标字符串的结尾。 [/code]
同样,我们也可以把“^”和“$”以及“\b”和“\B”看作是互为逆运算的两组定位符。举例来说: /^hell/ 因为上述正则表达式中包含“^”定位符,所以可以与目标对象中以 “hell”, “hello”或“hellhound”开头的字符串相匹配。 /ar$/ 因为上述正则表达式中包含“$”定位符,所以可以与目标对象中以 “car”, “bar”或 “ar” 结尾的字符串相匹配。 /\bbom/ 因为上述正则表达式模式以“\b”定位符开头,所以可以与目标对象中以 “bomb”, 或 “bom”开头的字符串相匹配。/man\b/ 因为上述正则表达式模式以“\b”定位符结尾,所以可以与目标对象中以 “human”, “woman”或 “man”结尾的字符串相匹配。
为了能够方便用户更加灵活的设定匹配模式,正则表达式允许使用者在匹配模式中指定某一个范围而不局限于具体的字符。例如:
[code] /[A-Z]/  上述正则表达式将会与从A到Z范围内任何一个大写字母相匹配。 /[a-z]/  上述正则表达式将会与从a到z范围内任何一个小写字母相匹配。 /[0-9]/  上述正则表达式将会与从0到9范围内任何一个数字相匹配。 /([a-z][A-Z][0-9])+/ 上述正则表达式将会与任何由字母和数字组成的字符串,如 “aB0” 等相匹配。 [/code]
这里需要提醒用户注意的一点就是可以在正则表达式中使用 “()” 把字符串组合在一起。“()”符号包含的内容必须同时出现在目标对象中。因此,上述正则表达式将无法与诸如 “abc”等的字符串匹配,因为“abc”中的最后一个字符为字母而非数字。
如果我们希望在正则表达式中实现类似编程逻辑中的“或”运算,在多个不同的模式中任选一个进行匹配的话,可以使用管道符 “|”。例如:/to|too|2/ 上述正则表达式将会与目标对象中的 “to”, “too”, 或 “2” 相匹配。
正则表达式中还有一个较为常用的运算符,即否定符 “[^]”。与我们前文所介绍的定位符 “^” 不同,否定符 “[^]”规定目标对象中不能存在模式中所规定的字符串。例如:/[^A-C]/ 上述字符串将会与目标对象中除A,B,和C之外的任何字符相匹配。一般来说,当“^”出现在 “[]”内时就被视做否定运算符;而当“^”位于“[]”之外,或没有“[]”时,则应当被视做定位符。
最后,当用户需要在正则表达式的模式中加入元字符,并查找其匹配对象时,可以使用转义符“\”。例如:/Th\*/  上述正则表达式将会与目标对象中的“Th*”而非“The”等相匹配。
在构造正则表达式之后,就可以象数学表达式一样来求值,也就是说,可以从左至右并按照一个优先级顺序来求值。优先级如下:
[code] 1.\ 转义符 2.(), (?:), (?=), [] 圆括号和方括号 3.*, +, ?, {n}, {n,}, {n,m} 限定符 4.^, $, \anymetacharacter 位置和顺序 5.|“或”操作 [/code]

使用实例
在JavaScript 1.2中带有一个功能强大的RegExp()对象,可以用来进行正则表达式的匹配操作。其中的test()方法可以检验目标对象中是否包含匹配模式,并相应的返回true或false。
我们可以使用JavaScript编写以下脚本,验证用户输入的邮件地址的有效性。
[code] <html> <head>   <script language="Javascript1.2">      <!-- start hiding      function verifyAddress(obj)      {       var email = obj.email.value;       var pattern = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/;       flag = pattern.test(email);       if(flag)       {        alert(“Your email address is correct!”);        return true;       }       else        {         alert(“Please try again!”);         return false;         }       }      // stop hiding -->     </script>   </head>   <body>    <form onSubmit="return verifyAddress(this);">     <input name="email" type="text">     <input type="submit">     </form>   </body> </html> [/code]

正则表达式对象
本对象包含正则表达式模式以及表明如何应用模式的标志。
[code] 语法 1 re = /pattern/[flags] 语法 2 re = new RegExp("pattern",["flags"]) [/code]
参数
re
必选项。将要赋值为正则表达式模式的变量名。

Pattern
必选项。要使用的正则表达式模式。如果使用语法 1,用 "/" 字符分隔模式。如果用语法 2,用引号将模式引起来。

Flags
可选项。如果使用语法 2 要用引号将 flag 引起来。标志可以组合使用,可用的有:
[code] g (全文查找出现的所有 pattern) i (忽略大小写) m (多行查找) [/code]

示例
下面的示例创建一个包含正则表达式模式及相关标志的对象(re),向您演示正则表达式对象的用法。在本例中,作为结果的正则表达式对象又用于 match 方法中:
[code] function MatchDemo() { var r, re; // 声明变量。 var s = "The rain in Spain falls mainly in the plain"; re = new RegExp("ain","g"); // 创建正则表达式对象。 r = s.match(re); // 在字符串 s 中查找匹配。 return(r); } [/code]

返回值: ain,ain,ain,ain\\
属性 lastIndex 属性 | source 属性\\
方法 compile 方法 | exec 方法 | test 方法\\
要求 版本 3\\
请参阅 RegExp 对象 | 正则表达式语法 | String 对象\\

exec 方法
用正则表达式模式在字符串中运行查找,并返回包含该查找结果的一个数组。
rgExp.exec(str)

参数

rgExp
必选项。包含正则表达式模式和可用标志的正则表达式对象。

str
必选项。要在其中执行查找的 String 对象或字符串文字。

说明\\
如果 exec 方法没有找到匹配,则它返回 null。如果它找到匹配,则 exec 方法返回一个数组,并且更新全局 RegExp 对象的属性,以反映匹配结果。数组的0元素包含了完整的匹配,而第1到n元素中包含的是匹配中出现的任意一个子匹配。这相当于没有设置全局标志 (g) 的 match 方法。
如果为正则表达式设置了全局标志,exec 从以 lastIndex 的值指示的位置开始查找。如果没有设置全局标志,exec 忽略 lastIndex 的值,从字符串的起始位置开始搜索。

exec 方法返回的数组有三个属性,分别是 input、index 和 lastIndex。Input 属性包含了整个被查找的字符串。Index 属性中包含了整个被查找字符串中被匹配的子字符串的位置。LastIndex 属性中包含了匹配中最后一个字符的下一个位置。

示例\\
下面的例子举例说明了 exec 方法的用法:
[code] function RegExpTest() { var ver = Number(ScriptEngineMajorVersion() + "." + ScriptEngineMinorVersion()) if (ver >= 5.5){ // 测试 JScript 的版本。 var src = "The rain in Spain falls mainly in the plain."; var re = /\w+/g; // 创建正则表达式模式。 var arr; while ((arr = re.exec(src)) != null) document.write(arr.index + "-" + arr.lastIndex + arr + "\t"); } else{ alert("请使用 JScript 的更新版本"); } } [/code]

返回值:0-3The 4-8rain 9-11in 12-17Spain 18-23falls 24-30mainly 31-33in 34-37the 38-43plain

test 方法\\
返回一个 Boolean 值,它指出在被查找的字符串中是否存在模式。
rgexp.test(str)

参数\\
rgexp
必选项。包含正则表达式模式或可用标志的正则表达式对象。

str
必选项。要在其上测试查找的字符串。

说明
test 方法检查在字符串中是否存在一个模式,如果存在则返回 true,否则就返回 false。
全局 RegExp 对象的属性不由 test 方法来修改。

示例
下面的例子举例说明了 test 方法的用法:
[code] function TestDemo(re, s) { var s1; // 声明变量。 // 检查字符串是否存在正则表达式。 if (re.test(s)) // 测试是否存在。 s1 = " contains "; // s 包含模式。 else s1 = " does not contain "; // s 不包含模式。 return("'" + s + "'" + s1 + "'"+ re.source + "'"); // 返回字符串。 } [/code]

函数调用:document.write (TestDemo(/ain+/ ,"The rain in Spain falls mainly in the plain."));

返回值:'The rain in Spain falls mainly in the plain.' contains 'ain+'

match 方法
使用正则表达式模式对字符串执行查找,并将包含查找的结果作为数组返回。\\
stringObj.match(rgExp)

参数\\
stringObj
必选项。对其进行查找的 String 对象或字符串文字。

rgExp
必选项。为包含正则表达式模式和可用标志的正则表达式对象。也可以是包含正则表达式模式和可用标志的变量名或字符串文字。

说明\\
如果 match 方法没有找到匹配,返回 null。如果找到匹配返回一个数组并且更新全局 RegExp 对象的属性以反映匹配结果。
match 方法返回的数组有三个属性:input、index 和 lastIndex。Input 属性包含整个的被查找字符串。Index 属性包含了在整个被查找字符串中匹配的子字符串的位置。LastIndex 属性包含了最后一次匹配中最后一个字符的下一个位置。
如果没有设置全局标志 (g),数组的 0 元素包含整个匹配,而第 1 到 n 元素包含了匹配中曾出现过的任一个子匹配。这相当于没有设置全局标志的 exec 方法。如果设置了全局标志,元素 0 到 n 中包含所有匹配。

示例\\
下面的示例演示了match 方法的用法:
[code] function MatchDemo() { var r, re; // 声明变量。 var s = "The rain in Spain falls mainly in the plain"; re = /ain/i; // 创建正则表达式模式。 r = s.match(re); // 尝试匹配搜索字符串。 return(r); // 返回第一次出现 "ain" 的地方。 } [/code]
返回值:ain

本示例说明带 g 标志设置的 match 方法的用法。
[code] function MatchDemo() { var r, re; // 声明变量。 var s = "The rain in Spain falls mainly in the plain"; re = /ain/ig; // 创建正则表达式模式。 r = s.match(re); // 尝试去匹配搜索字符串。 return(r); // 返回的数组包含了所有 "ain" // 出现的四个匹配。 } [/code]
返回值:ain,ain,ain,ain

上面几行代码演示了字符串文字的 match 方法的用法。
[code] var r, re = "Spain"; r = "The rain in Spain".replace(re, "Canada"); return r; [/code]
返回值:The rain in Canada

search 方法
返回与正则表达式查找内容匹配的第一个子字符串的位置。

stringObj.search(rgExp)

参数\\
stringObj
必选项。要在其上进行查找的 String 对象或字符串文字。

rgExp
必选项。包含正则表达式模式和可用标志的正则表达式对象。

说明

search 方法指明是否存在相应的匹配。如果找到一个匹配,search 方法将返回一个整数值,指明这个匹配距离字符串开始的偏移位置。如果没有找到匹配,则返回 -1。

示例\\
下面的示例演示了 search 方法的用法。
[code] function SearchDemo() { var r, re; // 声明变量。 var s = "The rain in Spain falls mainly in the plain."; re = /falls/i; // 创建正则表达式模式。 r = s.search(re); // 查找字符串。 return(r); // 返回 Boolean 结果。 } [/code]
返回值:18

Replace方法

返回根据正则表达式进行文字替换后的字符串的复制。
stringObj.replace(rgExp, replaceText)

参数

stringObj
必选项。要执行该替换的 String 对象或字符串文字。该字符串不会被 replace 方法修改。
rgExp
必选项。为包含正则表达式模式或可用标志的正则表达式对象。也可以是 String 对象或文字。
如果 rgExp 不是正则表达式对象,它将被转换为字符串,并进行精确的查找;
不要尝试将字符串转化为正则表达式。
replaceText
必选项。是一个String 对象或字符串文字,对于stringObj 中每个匹配 rgExp 中的位置都用
该对象所包含的文字加以替换。在 Jscript 5.5 或更新版本中,replaceText 参数也可以
是返回替换文本的函数。

说明

 

replace 方法的结果是一个完成了指定替换的 stringObj 对象的复制。

下面任意的匹配变量都能用来识别最新的匹配以及找出匹配的字符串。在需要动态决定替换字符串

的文本替换中可以使用匹配变量。

 

字符含义
$$$ (JScript 5.5 或更新版本)
$&指定与整个模式匹配的 stringObj 的部分。(JScript 5.5 或更新版本)
$`指定由 $& 描述的匹配之前的 stringObj 部分。(JScript 5.5 或更新版本)
$'指定由 $& 描述的匹配之后的 stringObj 部分。(JScript 5.5 或更新版本)
$n捕获的第 n 个子匹配,此处 n 为从1到9的十进制一位数。(JScript 5.5 或更新版本)
$nn捕获的第 nn 个子匹配,此处 nn 为从01到99的十进制两位数。(JScript 5.5 或更新版本)

 

如果 replaceText 为函数,对于每一个匹配的子字符串,调用该函数时带有下面的 m+3 个

参数,此处 m 是在 rgExp 中捕获的左括弧的个数。第一个参数是匹配的子字符串。

接下来的 m 个参数是查找中捕获的全部结果。第 m+2 个参数是在 stringObj 中匹配出现的偏移量,

而第 m+3 个参数为 stringObj。结果为将每一匹配的子字符串替换为函数调用的相应返回值的

字符串值。

 

replace() 方法的参数 replacement 可以是函数而不是字符串。在这种情况下,

每个匹配都调用该函数,它返回的字符串将作为替换文本使用。该函数的第一个参数是匹配模式

的字符串。接下来的参数是与模式中的子表达式匹配的字符串,可以有 0 个或多个这样的

参数。接下来的参数是一个整数,声明了匹配在 stringObject 中出现的位置。

最后一个参数是 stringObject 本身。

 

更有效的字符串替换:

<script language="javascript">
function replace(str,a,b)
    {
     var i;
     var s2 = str;
     while(s2.indexOf(a)>0)
     {
     i = s2.indexOf(a);
     s2 = s2.substring(0, i) + b
     + s2.substring(i + 2, s2.length);
     }
     return s2;
    }
</script>

发现一个我认为比原来的方法更有效率的字符串替换方法。
首先看看原来是怎么样做的:
程序代码
function toTXT(str){
     str = str.replace(/\&/g, "& amp;");
     str = str.replace(/\>/g, "& gt;");
     str = str.replace(/\</g, "& lt;");
     str = str.replace(/\"/g, "& quot;");
     str = str.replace(/\'/g, "& #39;");
     return str;
}
分析:上面的方法是用来替换过滤字符串的HTML代码的,一直认为这样做很没效率,

因为要把这个字符串进行5次全文匹配(不是数据库中的全文检索),有没方法只使

用一次全文匹配,就可以替换掉不同的字符串为不同的结果呢?
呵呵,终于找到了下面的这个方法:
程序代码
function toTXT(str){
     var RexStr = /\<|\>|\"|\'|\&/g
     str = str.replace(RexStr,
         function(MatchStr){
             switch(MatchStr){
                 case "<":
                     return "& lt;";
                     break;
                 case ">":
                     return "& gt;";
                     break;
                 case "\"":
                     return "& quot;";
                     break;
                 case "'":
                     return "& #39;";
                     break;
                 case "&":
                     return "& amp;";
                     break;
                 default :
                     break;
             }
         }
     )
     return str;
}

看上去要比第一个方法要复杂一些,写的代码也要多一点点,不过呢,只用一次,

就可以替换整个字符串里面的匹配字符为不同的结果,非常有效率的。而且代码看

上去也很直观,修改方便。


更重要的是第一个方法假如要替换"&"一定要放在最前面,而后面的方面完全不用担心这个问题。
JavaScript还有很多鲜为人知的用法,而且很多思想在别的语言里面都没有。

就算JAVA再怎么强大,他的正则表达式却在JDK1.4里面才引入,落后了很多。

不过我没说JAVA就一定比JS差只类的话啊。


JS的应用范围绝对不止HTML,还有很多其他的方面都在使用他,

比如WebFT(测试网站的工具),.NET等,并且在即将发布,传说中“FLASH杀手”

——WPF/E(Windows Presentation Foundation/Everywhere)出现后,

JS的应用范围更加宽广。


很多人都不屑于JS,认为他很低级,连基本的对象类型都没有。NO,错了,在.NET里面,

也就是Jscript.Net中,微软将JS的版本提升为8.0,基本上他已经与C#没有任何差别,

所有程序语言该有的他都具备了。


说一个笑话,我写.net和ASP就用的Jscript,但是VB和C#我也并不是属于那种泛泛而谈

的类型,只是我觉得假如可以用一门语言从后写到前,包括他的周边项目,那将是一件

非常惬意的事情。从此再也不会在多种语言中转来转去了。

 

 

Replace 方法更新全局 RegExp 对象的属性。

示例

下面的示例演示了 replace 方法将第一次出现的单词 "The" 替换为单词 "A" 的用法。

function ReplaceDemo(){
var r, re; // 声明变量。
var ss = "The man hit the ball with the bat.\n";
ss += "while the fielder caught the ball with the glove.";
re = /The/g; // 创建正则表达式模式。
r = ss.replace(re, "A"); // 用 "A" 替换 "The"。
return(r); // 返回替换后的字符串。
}

另外, replace 方法也可以替换模式中的子表达式。下面的范例演示了交换字符串中的每一对单词:

function ReplaceDemo(){
var r, re; // 声明变量。
var ss = "The rain in Spain falls mainly in the plain.";
re = /(\S+)(\s+)(\S+)/g; // 创建正则表达式模式。
r = ss.replace(re, "$3$2$1"); // 交换每一对单词。
return(r); // 返回结果字符串。
}

下面的示例(在 JScript 5.5 及更新版本中执行)执行的是从华氏到摄氏的转换,它演示了使用

函数作为 replaceText。要想知道该函数是如何工作的,传递一个包含数值的字符串,数值后要

紧跟 "F" (例如 "Water boils at 212")。

 

function f2c(s) {
var test = /(\d+(\.\d*)?)F\b/g; // 初始化模式。
return(s.replace
(test,
function($0,$1,$2) {
return((($1-32) * 5/9) + "C");
}
)
);
}
document.write(f2c("Water freezes at 32F and boils at 212F."));

function($0,$1,$2) {
return((($1-32) * 5/9) + "C");
}
)
);
}
document.write(f2c("Water freezes at 32F and boils at 212F."));
 
自己写的两个方法:
<html>
<SCRIPT LANGUAGE="JavaScript">
<!--
function replaceAll(str,b){
//var renStr=str.replace("-","*");这样写只能替换第一个匹配的字符.
var renStr=str.replace(/\-/g,b);//这样写可以替换匹配的字符所有字符.
与replaceAllNew()方法作用是一样的.

document.all.text4.value=renStr;
document.all.text2.value="";
document.all.text3.value="";
}
function replaceAllNew(text,replacement,target){
if(text==null || text=="") return text;//如果text无内容,返回text
if(replacement==null || replacement=="") return text;//如果replacement无内容,返回text
if(target==null) target="";//如果target无内容,设置为空串
var returnString="";//定义返回值变量,并初始化
var index=text.indexOf(replacement);//定义查找replacement的索引下标,并进行第一次查找
while(index!=-1)
{//直至未找到replacement,要么进行下面的处理
//alert(index);
//alert(returnString);
returnString+=text.substring(0,index)+target;//如果找到的replacement前有字符,
累加到返回值中,并加上target
text=text.substring(index+replacement.length);//取掉找到的replacement及前边的字符
index=text.indexOf(replacement);//进行查询,准备下一次处理
}
if(text!="") returnString+=text;//如果找到的最后一个replacement后有字符,累加到返回值中
//alert(returnString);
document.all.text4.value=returnString;
document.all.text2.value="";
document.all.text3.value="";
return returnString;//返回
}
function bodyOnload(){
var str1="adbddasd";
//replaceAll(str1,'a','A');
}
//-->
</SCRIPT>
<body >
1:javascript 中的replace方法测试!<br>
原来的:<input type="text" value="">;转换后的:<input type="text" value=""><br>
把字符:<input type="text" value=""><br>
替换为:<input type="text" value=""><br>
<input type="button" value="replace1" />
<input type="button" value="replace2" />
</body>
</html>

2008年3月7日星期五

here.getMyVoice(setJob("Developer"),setDelayWeek(1));

我: well, I'm working on an administration system which works in background

and i heard that your wife has come here, hehe

发送时间下午4:46 on 星期五

我: i think the background system is not so easy for me to work on, i must pay more attention on all kinds of tables and keys and sequences in the database....it needs more patience

发送时间下午4:50 on 星期五

我: and the framework used in our system is only struts, we don't use hibernate and spring at all.

发送时间下午4:51 on 星期五

我: for the database operation, we use DAO instead, and all kinds of DAO and DBAction wraps the database operations all together.

2008年2月23日星期六

离别ITC

昨天刚刚在ITC办完了离职手续。当迈出办公室的门的刹那,心情复杂到了极点。有一些温热的东西在眼眶里打转,但是自己强忍着没让他流出来。


想一想前一天还在工作岗位上测试手机,而今天一下午的时间就办完了离职手续,自己都有点不敢相信这是真的。但是事实还是这样发生了,就是这么的不可思议。


或许人就是这样,只有当离开一个地方的时候才会有感伤,尽管之前自己曾经那样抱怨它容不下一个小小的自己。


离开了对自己非常照顾的组长亚各,离开了每天都很Happy的女强人Rainy,离开了优雅的秒针,更离开了自己最最舍不得的武汉5人。出门的一刹那,自己甚至不敢再多看他们一眼,但偏偏又看见了刚入职一个月的Frank,想起他跟我说过的跳槽经历。。。


在公司电脑上做的最后一件事情就是把MSN签名改成了“山水的转换不过是过眼云烟,对自己的追求要坚持不懈”。然而我真的能做到把山水的转换当成是过眼云烟么?


从电梯里出来,偶尔听到写字楼前台在放郑智化的《水手》:“他说风雨中这点痛算什么,擦干泪不要怕,至少我们还有梦”。是的。不可以回头,为了这个梦我期待了多久阿。。。现在终于梦想成真了。。。


山水的变化或许不是过眼云烟,但是对自己的追求必须坚持不懈!!!

2008年2月11日星期一

[转]张家口话四级考试

张家口话四级考试试卷


考生注意:
            1、本试卷共1页,总分150分,考试时间120分钟。
            2、答卷前将密封线左侧的项目填写清楚。  
            3、答案须用蓝色、黑色钢笔或圆珠笔书写。

第一部分:基础 

一.选择题:请仔细阅读题目,选出跟题目意思最接近的选项.  (每题5分,公30分)

1.你老鼓捣甚了?
   A:您老人家做什么呢?            B:你一直都在做什么呢?      C:你是叫老鼓捣吗?
2.再个女女真酸真捏.
   A:这闺女真漂亮.                   B:这闺女真做作.                  C:那边有个女的身上都酸了,真的!
3.你夜来个是不又蹲底了?
   A:你晚上是不是又要蹲床底下? 
   B:你昨天是不又闯祸了?
   C:你晚上是不又不回来了?
4.你真不机米.
   A:你真帅.                             B:你真难看.                         C.你真傻.
5.你看看你那个脸,油子没念的跟个猪犊子一撒的.
   A:你看看你的脸,脏的跟个猪屁股似的.
   B.你看你长的跟只小猪似的.
   C.你那边那只脸咋全是猪油?
6.额先去丢个盹个,不跟你耍藏老妹妹了,乏列.
   A.你快把我的小妹妹放出来吧,别老藏着了,不好玩.
   B.我先去睡会,不跟你玩捉迷藏了,累了.
   C.当心我去把这东西扔了,不跟你废话了,怕了吧.

二.名词解释:解释下列各组字型相近名词,并各造句.  (每题5分,公20分)

  1.二狗油    二五眼 .
  2.疙得白    疙碴  .
  3.俏货       鲜货  .
  4.各狍       各几眼  .


第二部分:阅读理解

三.阅读短文,回答问题. (公30分)

       人哇,最值钱儿的就是你乃条敏,乃东西噶人就一回.乃你说说再定咋马个儿过了?多会你思慕原来个儿哇,你不能说是德蓝二性就老撒的球迷幸眼,一不能说是逼吗呼出就老撒的各出马蛋的.就再么个儿,等你看的快各级眼那会你才将能比上叨叨, 饿的再条敏跟再一辈子乃点日能能尽割显的满世杰可展锅的乃马点四儿列——让满世杰的孩儿们都能动弹闹的架.

  1.本文选自(        ),作者是(       ),他是(    )著名作家,生于(    )年,死于(    )年.  (10分,每空2分)
  2.解释文中画线部分,并将其翻译为英语.       (10分,解释和翻译各5分)
  3.用纯正的张家口口音朗诵这段话.(需音容并茂,要求表达出作者所要表达的感情)         (10分)

四.翻译下面一句话,并用纯正的张家口口音朗诵.(10分)

     树上各就俩鸟,母鸟对公鸟说:“搁挤甚了,你往内面儿各就各就,别把饿的毛衣压个出了!”公鸟说:“你真麻秋翻,个出了你不拉不拉不就展了!”


第三部分:写作

五.将下列这段英文翻译成张家口话.(20分)

    To be, or not to be- that is the question:
Whether it's nobler in the mind to suffer
The slings and arrows of outrageous fortune
Or to take arms against a sea of troubles,
And by opposing end them. To die- to sleep-
No more; and by a sleep to say we end
The heartache, and the thousand natural shocks
That flesh is heir to. It's a consummation
Devoutly to be wished.

六.作文.(40分)

题材:一只鹰抓了一只羊,这时,被一只乌鸦看到了,乌鸦想学鹰抓羊,但由于能力不够,结果又被牧羊人抓到了。
要求:1.根据对材料的理解,写一篇800字的作文.
        2.念给张家口文盲其可以听懂.
        3.除诗歌戏剧外题材不限.

2008年2月7日星期四

献给小三:解决关机后鼠标仍然发光问题

随着电脑硬件高速度的发展,大多数用户现在所用的鼠标都是光电鼠标。你有没有碰到在你电脑关机后鼠标仍然发光的时候?或许你会认为那是鼠标正常显示的状态,但其实是你的设置导致此类情况的发生。

   导致这一情况的主要原因是主板的键鼠开机功能。大家可以进入BIOS主菜单的 “Power Management Setup”页面找到“S3 KB Wake-Up Function”将其设置为“Disable”,关闭主板对键鼠的+5VSB供电,PS/2光电鼠在关机之后自然就不会亮了。另外,有些USB光电鼠标也会在关机后继续发光,解决的方法基本和PS/2相似,进入BIOS主菜单的“Power Management Setup”页面,将“USB Wake-Up From S3 ”选项设置为“Disable”就可以解决这一问题了。

   以上是解决鼠标关机后仍然发光的一些办法,希望能对您有所帮助。

2008年2月6日星期三

新春有感

回首过去的一年,经历了坎坷,经历了分别,但是收获了一些成熟,也收获了许多朋友。

要感谢的人真的太多。

首先要感谢父母。24年来,来自他们的所有的关爱使我不断成长,包括我的每一个决定,每一个改变,他们都给了我莫大的支持!我是幸福的……

然后要感谢我的老师们。进入社会才感觉到,这十几年的知识积淀是那么的必要,却又是那么的不足。感谢老师传授给我的知识和做人的道理,也特别怀念在教室里度过的每分每秒。现在看来,那些时刻都是那么珍贵。而我很有幸成为这么多优秀的老师的学生。我是幸福的……

接下来感谢我的朋友们。在年底我做出的这个重要决定中,有高中时代的朋友献计献策,有大学室友的鼎力相助,有隔壁宿舍的哥们儿深夜给我传道授业,有武汉实习期间认识的Java高手指点迷津,更有来自Team Leader的谆谆教诲,也有现在室友的理解和鼓励……这个时刻,我深刻的体会到“在家靠父母,出门靠朋友”这句话的含义。而我想说的是,真的很感谢你们!

新的一年,祝福所有在我困难时候帮助我的人,在我无助的时候鼓励我的人,以及所有在我得意和失意的时候打击我的人,祝愿你们,也祝福我自己,

 

2008万象更新,福星高照!

 

 

2008年2月2日星期六

Before I leave

Some words reminds me that, you must put your GOAL in your mind AT ANY TIME, and always remember the PROGRESS!

Thanks, Jeff!

I'll improve!

Hit the GOAL and control the PROGRESS!

2008年1月25日星期五

身心俱疲的我

从来不担心自己的未来

从来不去想自己的现在

四年的时间一晃而过

我用6个月的时间

换来了一个如此丑陋的自己

自私、敏感、不负责任……

所有这些

一个新的自卑的我诞生了!

 

我奔跑在发狂的路上

疯狂的笑着

可是当我回头

却发现四周一片沉寂

我彻底的感到疲惫

 

死亡?毁灭?

我现在还惧怕什么

这一切很快就结束了

 

路的尽头也许只有无尽的路

而我

在这漫长的路上该做些什么?

2008年1月9日星期三

理解Struts流程和ActionServlet

Struts controller基本功能是:
1. 截获用户的Http请求
2. 把这个请求映射到相应的Action类,如果这是此类收到的第一个请求,将初始化实例并缓存。
3. 创建或发现一个ActionForm bean实例(看配置文件是否定义),然后将请求过程移植到bean,填充所需的各个参数。
4. 调用Action实例的perform()方法并将ActioForm bean,Action Mapping对象,request和response对象传给它。

如:public ActionForword perform(ActionMapping mapping, ActionForm form,HttpServletRequest request,HttpServletResponse response)
5.perform返回一个ActionForword对象,此对象连接到相应的jsp 。

6.  ActionForward 出来后,还是交给 ActionServlet ,form / request 还在。只要没有 response ,request 还可以由 ActionServlet 转交给别的 aciton 而做别的事情。

ActionServlet使用ActionForm bean来保存请求的参数,这些bean的属性名称与HTTP请求参数的名称相对应,控制器将请求参数传递到ActionForm bean的实例,然后将这个实例传送到Action类。
      典型的ActionFrom bean只有属性的设置与读取方法(getXXX),而没有实现事务逻辑的方法。只有简单的输入检查逻辑,使用的目的是为了存储用户在相关表单中输入的最新数据,以便可以将同一网页进行再生,同时提供一组错误信息,这样就可以让用户修改不正确的输入数据。而真正对数据有效性进行检查的是ACTION类或适当的事务逻辑bean。

有几个部分共同组成了Struts 的Controller,用户的请求发送到ActionServlet中,ActionServlet调用RequestProssor开始处理用户请求的流程,在这个流程中,会查找ApplicationConfig,得到用户请求对应的Action,调用相应的Action来具体执行用户的请求,最后返回ActionForward,转向相应的流程。
        org.apache.struts.action.ActionServlet  是Struts Controller中最主要的部分,所有用户请求都会被发送到这里,所有的其它处理也必须从这里经过。它是从 HttpServlet中继承过来的, 当它接收到HTTP request的时候,不管是doGet()或者doPost()方法,都会调用process()方法。
protected void process(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException

{ RequestUtils.selectApplication( request, getServletContext() ); 

getApplicationConfig(request).getProcessor().process( request, response );

}
        一般情况下,我们不需要自己实现或者修改ActionServlet类,仅仅使用就可以了。某些情况下,我们可以自己扩展 ActionServlet类,从ActionServlet继承,实现自己的MyActionServlet类。覆盖其中的一些方法来达到你的特殊处理的需要。

       ActionServlet继承自javax.servlet.http.HttpServlet,所以在本质上它和一个普通的servlet没有区别,你完全可以把它当做一个servlet来看待,只是在其中完成的功能不同罢了。

        RequestProssor具体处理用户的request,作为一个request handler存在。同样,处理request的时候,会执行RequestProcessor类中的process(execute)方法。
      process 中调用的方法都是可以重载的,如果有需要,可以实现为自己特定的方法。比如,对于Locale问题,通常都是在系统最一开始加载的时候读取的,如果用户想在任何时刻都可以切换或者选择自己的Locale,我们就可以重载processLocale()方法。然后只需要在配置文件中加入段就可以了
        Action 类是实现整个体系的核心部分,它在客户请求、界面表示和业务逻辑之间起到一个桥梁的作用。每一个Action都用来处理某一项任务,或者进行一个业务操作。当然了,我们说一项任务不是说Action只实现一个业务操作方法,而是集中实现某一个功能单元。比如登录用的LogonAction、查找用的 SearchAction等等。Action是在RequestProcessor中,由processActionPerform方法调用的
      非常重要的一点:不要在Action中包含任何业务逻辑操作,而是应该调用一个Model层的JavaBean来实现你的业务逻辑操作。在某些情况下,可能包含少许表现逻辑。这样,就可以充分进行代码重用,比如上例中调用的IStorefrontService接口,这个接口在实现时完全可以不用考虑客户端的事情,所以它可以被其它部分或者其它系统所使用。否则的话,Action会变得非常难于理解,难于维护,代码也不能重用。
       struts-example工程的设计就是一个bug,它把业务逻辑封装到了Action类中
      在Action 的execute方法中,返回一个ActionForward类。

       ActionForward把配置文件中forward部分的信息包装起来,减少了应用程序和物理资源信息之间的耦合性。通过ActionMapping类,可以在配置文件中查找相应的forward信息。例如,对于一个 LoginAction它的配置信息可能是这样的:
     返回的ActionForward就会包含段中的信息。在ActionMapping类的findForward方法中,首先会根据查找forward的name查找是否有相应的forward段,如果没有,则在配置文件中的段中进行查找,如果还没有就会抛出一个例外。
        以前,页面上的输入数据都通过HTTP request提交,服务方检索出输入的数据,进行验证,然后将这些数据传递给其它组件进行业务处理。一切基本都需要手工编写代码进行操作,比较麻烦,也使代码变得复杂。
       ActionForm[org.apache.struts.action.ActionForm]用来收集用户的输入,并且把这些信息传递给Action对象,然后,在Action对象中,ActionForm中的数据被取出来传递给业务逻辑层进行处理。
ActionForm一方面作为一个缓冲区,临时存储用户输入的数据;另一方面,可以把ActionForm当成是HTTP和Action之间的一个防火墙,它可以验证输入数据的正确性,如果验证不通过,这个request是不会发送给Action进行处理的。
        ActionForm可以有两种Scope,request或者session。request就是只能在rquest到response,之后ActionForm就不可见了;session可以保存时间长一点。
       在ActionForm的Validate方法中返回的是ActionErrors对象。这个对象可以将错误信息都封装起来,并且自动把它们显示给用户。
       在相应JSP页面上添加,可以自动将ActionErrors中的错误信息显示出来。包括,每一个具体的,通过add添加的错误信息,和一个ErrorHeader和一个ErrorFooter,这些都可以通过配置文件指定,并且可以包含HTML语法。
Struts提供了四种自定义Tag库:
bean:struts-bean taglib包含在访问bean和bean属性时使用的tag,也包含一些消息显示的tag。
html:struts-html taglib包含用来创建struts输入表单的tag,和其它通常用来创建基于HTML用户界面的tag。
logic:struts-logic taglib包含的tag用来管理根据条件生成输出文本,和其它一些用来控制的信息。
template:struts-template taglib包含的tag用来定义模板机制。

以下是一个范例:

reguser.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="/WEB-INF/Struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/Struts-html.tld" prefix="html" %>
<html:html locale="true">
<head>
<title>RegUser</title>
<html:base/>
</head>
<body bgcolor="white">
<html:errors/>
<html:form action="/regUserAction" focus="logname">
<table border="0" width="100%">
  <tr>
    <th align="right">
      Logname:
    </th>
    <td align="left">
      <html:text property="logname" size="20" maxlength="20"/>
    </td>
  </tr>
  <tr>
    <th align="right">
      Password:
    </th>
    <td align="left">
      <html:password property="password" size="20" maxlength="20"/>
    </td>
  </tr>
  <tr>
    <th align="right">
      E-mail:
    </th>
    <td align="left">
      <html:password property="email" size="30" maxlength="50"/>
    </td>
  </tr>
  <tr>

struts-config.xml:

<Struts-config>
<form-beans>
<form-bean      name="regUserForm"
type="org.cjea.Struts.example. RegUserForm "/>
</form-beans>
<action-mappings>
<action  path="/regUserAction"
        type=" org.cjea.Struts.example.RegUserAction "
        attribute=" regUserForm "
        scope="request"
        validate="false">
      <forward name="failure"   path="/ messageFailure.jsp"/>
      <forward name="success"  path="/ messageSuccess.jsp"/>
</action>
</action-mappings>
</Struts-config>

RegUserForm:

import javax.Servlet.http.HttpServletRequest;
import org.apache.Struts.action.ActionForm;
import org.apache.Struts.action.ActionMapping;

public final class RegUserForm extends ActionForm{

  private String logname;
  private String password;
  private String email;

  public RegUserForm(){
    logname = null;
    password = null;
    email = null;
  }

  public String getLogName() {
    return this.logname;
  }
  public void setLogName(String logname) {
    this.logname = logname;
  }
  public void setPassWord(String password) {
    this.password = password;
  }
  public String getPassWord() {
    return this.password;
  }
  public void setEmail(String email) {
    this.email = email;
  }
  public String getEmail() {
    return this.email;
  }

  public void reset(ActionMapping mapping, HttpServletRequest request)
    {
        logname = null;
        password = null;
        email = null;
    }
}

RegUserAction :

import javax.Servlet.http.*;
import org.apache.Struts.action.*;

public final class RegUserAction extends Action
{

public ActionForward perform(ActionMapping mapping,
  ActionForm form,  HttpServletRequest req,
  HttpServletResponse res)
{ 
  String title = req.getParameter("title");
  String password = req.getParameter("password");
  String email = req.getParameter("email");
  }
}

2008年1月7日星期一

变化

这个周一似乎特别不寻常。

起先是看到大勇的博客,里面叙述了他经历了城市的变化以后的心情。看着他的博客从离开北京以后就一直以“离开北京的第XX天”为标题,突然有一种特别的伤感涌上心头。特别是当我看到那句“不知道班长起床有没有快一点……不知道现在谁在陪小三抽烟……”,心里一阵阵难受。。。想想自己也曾在某个晚上下班回家的路上跟小三提起了大勇,当时心里也是有一点点伤感,但是毕竟还不很强烈。但是看到大勇写的这些字句,心里就特别涌起一股伤感的热流,而这种感觉是在虹口足球场的地铁站入口处第一次碰到的。。。

接着就是Alb-Skyer回复的短信,搞得自己一头雾水。好像是出了什么特别麻烦的事情,让我一下子就担心起来。虽然AS不希望我多过问,但是心里总是有点放不下,不知道他到底怎样了。唉。。。或许是我太喜欢操心了吧。。。

晚上回来,Fbo也异常的忙,都没有时间回复我的QQ留言,而且变得超级冷漠。。。

不知道为什么,感觉自己是一成不变,但是周围的一切确实变化万千。。。

我真的晕了……

什么时候我也能发生变化呢?

一切都不确定……