.NET 框架的正则表达式类


  下面通过介绍 .NET 框架的正则表达式类,熟悉一下.NET框架下的正则表达式的使用方法。

  3.1 Regex 类表示只读正则表达式

  Regex 类包含各种静态方法,允许在不显式实例化其他类的对象的情况下使用其他正则表达式类。以下代码示例创建了 Regex 类的实例并在初始化对象时定义一个简单的正则表达式。请注意,使用了附加的反斜杠作为转义字符,它将 \s 匹配字符类中的反斜杠指定为原义字符。

Regex r; // 声明一个 Regex类的变量
r = new Regex("\\s2000"; // 定义表达式 

  3.2 Match 类表示正则表达式匹配操作的结果

  以下示例使用 Regex 类的 Match 方法返回 Match 类型的对象,以便找到输入字符串中第一个匹配。此示例使用 Match 类的 Match.Success 属性来指示是否已找到匹配。

Regex r = new Regex("abc"; // 定义一个Regex对象实例
Match m = r.Match("123abc456"; // 在字符串中匹配
if (m.Success) 
{
 Console.WriteLine("Found match at position " + m.Index); //输入匹配字符的位置


  3.3 MatchCollection 类表示非重叠匹配的序列

  该集合为只读的,并且没有公共构造函数。MatchCollection 的实例是由 Regex.Matches 属性返回的。使用 Regex 类的 Matches 方法,通过在输入字符串中找到的所有匹配填充 MatchCollection。下面代码示例演示了如何将集合复制到一个字符串数组(保留每一匹配)和一个整数数组(指示每一匹配的位置)中。

MatchCollection mc;
String[] results = new String[20];
int[] matchposition = new int[20];
Regex r = new Regex("abc"; //定义一个Regex对象实例
mc = r.Matches("123abc4abcd"
for (int i = 0; i < mc.Count; i++) //在输入字符串中找到所有匹配
{
 results[i] = mc[i].Value; //将匹配的字符串添在字符串数组中
 matchposition[i] = mc[i].Index; //记录匹配字符的位置


  3.4 GroupCollection 类表示捕获的组的集合

  该集合为只读的,并且没有公共构造函数。GroupCollection 的实例在 Match.Groups 属性返回的集合中返回。下面的控制台应用程序查找并输出由正则表达式捕获的组的数目。 

using System;
using System.Text.RegularExpressions;
public class RegexTest 
{
 public static void RunTest() 
 {
  Regex r = new Regex("(a(b))c"; //定义组
  Match m = r.Match("abdabc";
  Console.WriteLine("Number of groups found = " + m.Groups.Count);
 }
 public static void Main() 
 {
  RunTest();
 }


  该示例产生下面的输出:

Number of groups found = 3 

  3.5 CaptureCollection 类表示捕获的子字符串的序列 

  由于限定符,捕获组可以在单个匹配中捕获多个字符串。Captures属性(CaptureCollection 类的对象)是作为 Match 和 group 类的成员提供的,以便于对捕获的子字符串的集合的访问。例如,如果使用正则表达式 ((a(b))c)+(其中 + 限定符指定一个或多个匹配)从字符串"abcabcabc"中捕获匹配,则子字符串的每一匹配的 Group 的 CaptureCollection 将包含三个成员。

  下面的程序使用正则表达式 (Abc)+来查找字符串"XYZAbcAbcAbcXYZAbcAb"中的一个或多个匹配,阐释了使用 Captures 属性来返回多组捕获的子字符串。 

using System;
using System.Text.RegularExpressions;
public class RegexTest 
{
 public static void RunTest() 
 {
  int counter;
  Match m;
  CaptureCollection cc;
  GroupCollection gc;
  Regex r = new Regex("(Abc)+"; //查找"Abc"
  m = r.Match("XYZAbcAbcAbcXYZAbcAb"; //设定要查找的字符串
  gc = m.Groups;
  //输出查找组的数目
  Console.WriteLine("Captured groups = " + gc.Count.ToString()); 
  // Loop through each group.
  for (int i=0; i < gc.Count; i++) //查找每一个组
  {
   cc = gc[i].Captures;
   counter = cc.Count;
   Console.WriteLine("Captures count = " + counter.ToString());
   for (int ii = 0; ii < counter; ii++) 
   {
    // Print capture and position.
    Console.WriteLine(cc[ii] + " Starts at character " + 
    cc[ii].Index); //输入捕获位置
   }
  }
 }
 public static void Main() {
  RunTest();
 }


  此例返回下面的输出结果:

Captured groups = 2
Captures count = 1
AbcAbcAbc Starts at character 3
Captures count = 3
Abc Starts at character 3
Abc Starts at character 6
Abc Starts at character 9 

  3.6 Capture 类包含来自单个子表达式捕获的结果

  在 Group 集合中循环,从 Group 的每一成员中提取 Capture 集合,并且将变量 posn 和 length 分别分配给找到每一字符串的初始字符串中的字符位置,以及每一字符串的长度。

Regex r;
Match m;
CaptureCollection cc;
int posn, length;
r = new Regex("(abc)*";
m = r.Match("bcabcabc";
for (int i=0; m.Groups[i].Value != ""; i++) 
{
 cc = m.Groups[i].Captures; 
 for (int j = 0; j < cc.Count; j++) 
 {
  posn = cc[j].Index; //捕获对象位置
  length = cc[j].Length; //捕获对象长度
 }


samanthacsharp 发表于 >2006-1-26 17:13:45 保存该日志到本地 [全文] [评论] [引用] [推荐] [档案] [推给好友] [收藏到网摘]

 

2006-1-26
正则表达式

using System.Text.RegularExpressions;
^符号匹配字符串的开头。
$符号匹配字符串的结尾。
*符号匹配0个或多个前面的字符。
+符号匹配至少一个前面的字符。
?符号匹配0个或1个前面的字符。
.符号匹配除换行符以外的任何字符。
x|y匹配“x”或“y”。
{n}匹配恰好n次(n为非负整数)前面的字符。
{n,}匹配至少n次(n为非负整数)前面的字符。
{m,n}匹配至少m个,至多n个前面的字符。
[xyz]表示一个字符集,匹配括号中字符的其中之一。
[abc] 匹配“a”、“b”和“c”
[^xyz]表示一个否定的字符集。匹配不在此括号中的任何字符。
[a-z]表示某个范围内的字符,匹配指定区间内的任何字符。例如:
[^m-n]表示某个范围之外的字符,匹配不在指定范围内的字符。例如:
\符号是转义操作符。例如:
\n 换行符
\f 分页符
\r 回车
\t 制表符
\v 垂直制表符
\\ 匹配“\”
\/ 匹配“/”

\s 任何白字符,包括空格、制表符、分页符等。等价于“[ \f\n\r\t\v]”
\S 任何非空白的字符。等价于“^\f\n\r\t\v]”
\w 任何单词字符,包括字母和下划线。等价于“[A-Za-z0-9_]”
\W 任何非单词字符。等价于“[^A-Za-z0-9_]”
\b匹配单词的结尾。
\B匹配单词的开头。
\d匹配一个数字字符,等价于[0-9]。
\D匹配一个非数字字符,等价于[^0-9]。
\NUM匹配NUM个(其中NUM为一个正整数),引用回到记住的匹配。例如:
      (.)\1 匹配两个连续相同的字符。 
\oNUM匹配n(其中n为一个小于256的八进制换码值)。例如:
      \o011 匹配制表符
\xNUM匹配NUM(其中NUM为一个小于256的十六进制换码值)。例如:
      \x41 匹配字符“A”


"^\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


$number   替换由组号 number(十进制)匹配的最后一个子字符串。 
${name}   替换由 (?<name>  组匹配的最后一个子字符串。 
$$        替换单个“$”字符。 
$&        替换完全匹配本身的一个副本。 
$`        替换匹配前的输入字符串的所有文本。 
$'        替换匹配后的输入字符串的所有文本。 
$+        替换最后捕获的组。 
$_        替换整个输入字符串。 

分组构造

(                 捕获匹配的子字符串(或非捕获组;有关详细信息,请参见正则表达式选项中的 ExplicitCapture 选项)。使用 () 的捕获根据左括号的顺序从 1 开始自动编号。捕获元素编号为零的第一个捕获是由整个正则表达式模式匹配的文本。 
(?<name>          将匹配的子字符串捕获到一个组名称或编号名称中。用于 name 的字符串不能包含任何标点符号,并且不能以数字开头。可以使用单引号替代尖括号,例如 (?'name')。 
(?<name1-name2>   平衡组定义。删除先前定义的 name2 组的定义并在 name1 组中存储先前定义的 name2 组和当前组之间的间隔。如果未定义 name2 组,则匹配将回溯。由于删除 name2 的最后一个定义会显示 name2 的先前定义,因此该构造允许将 name2 组的捕获堆栈用作计数器以跟踪嵌套构造(如括号)。在此构造中,name1 是可选的。可以使用单引号替代尖括号,例如 (?'name1-name2')。 
(?:               非捕获组。 
(?imnsx-imnsx:    应用或禁用子表达式中指定的选项。例如,(?i-s:  将打开不区分大小写并禁用单行模式。有关详细信息,请参见正则表达式选项。 
(?=               零宽度正预测先行断言。仅当子表达式在此位置的右侧匹配时才继续匹配。例如,\w+(?=\d)             与后跟数字的单词匹配,而不与该数字匹配。此构造不会回溯。 
(?!               零宽度负预测先行断言。仅当子表达式不在此位置的右侧匹配时才继续匹配。例如,\b(?!un)\w+\b 与不以 un 开头的单词匹配。 
(?<=              零宽度正回顾后发断言。仅当子表达式在此位置的左侧匹配时才继续匹配。例如,(?<=19)99 与跟在 19 后面的 99 的实例匹配。此构造不会回溯。 
(?<!              零宽度负回顾后发断言。仅当子表达式不在此位置的左侧匹配时才继续匹配。 
(?>               非回溯子表达式(也称为“贪婪”子表达式)。该子表达式仅完全匹配一次,然后就不会逐段参与回溯了。(也就是说,该子表达式仅与可由该子表达式单独匹配的字符串匹配。) 


Regex 类有大量的方法和属性,如果您以前没有用过它,可能会感到无所适从。下面汇总了一些最常用的方法:

方法 说明 
Escape / Unescape
字符串中的转义元字符,用作表达式中的文字。
 
IsMatch
如果正则表达式在输入字符串中发现匹配,返回“Ture”。
例如,下面的函数演示了如何使用正则表达式验证邮政编码:
private void ValidateZipButton_Click(object sender, System.EventArgs e)
{
   String ZipRegex = @"^\d{5}$";
   if(Regex.IsMatch(ZipTextBox.Text, ZipRegex))
   {
      ResultLabel.Text = "ZIP is valid!";
   }
   else
   {
      ResultLabel.Text = "ZIP is invalid!";
   }
}


 
Match
如果在输入字符串中发现匹配,则返回匹配对象。
string input="
以下内容为程序代码:
[img] 截取到 [/img]
";
Regex reg=new Regex(@"
以下内容为程序代码:
(?<=[img].*?(?=[/img])
";
string output=reg.Match(input).Value;
 
Matches
如果在输入字符串中发现包含任何或全部匹配,则返回匹配集合对象。
可以使用如下代码遍历输入字符串的匹配集合:

从URL提取协议和端口号
string Extension(string URL)
{
Regex r = new Regex(@"^(?<protol>\w+)://[^/]+?(?<port>:\d+)?/",RegexOptions.Compiled);
return r.Match(URL).result("${protol}${port}";
}


private void MatchButton_Click(object sender, System.EventArgs e)
{
   MatchCollection matches = Regex.Matches(SearchStringTextBox.Text, 
MatchExpressionTextBox.Text);
   MatchCountLabel.Text = matches.Count.ToString();
   MatchesLabel.Text = "";
   foreach(Match match in matches)
   {
      MatchesLabel.Text += "Found" + match.ToString() + " at 
position " + match.Index + ".<br>";
   }
}

 
Replace
用给定的替换字符串替换输入字符串中的匹配。
可以使用静态 Replace() 方法将匹配替换为特定字符串,如下所示:

String newText = Regex.Replace(inputString, pattern, replacementText);

更改日期格式(用dd-mm-yy的日期形式替代mm/dd/yy的日期形式)
string MDYToDMY(string input)
{
return Regex.Replace(input,@"\b(?<month>\\d{1,2})/(?<day>\\d{1,2}/(?<year>\\d{1,2}\b","${day}-${month}-${year}";
}

Split
将输入字符串拆分成用正则表达式匹配分开的数组元素时,返回数组字符串。
 

除了指定很多方法外,还有一些选项可以指定,通常在 Regex 对象构造函数中。由于这些选项是位屏蔽的一部分,或许可以同时指定这些选项(如,可以同时指定 Multiline 和 Singleline)。

通常,在您需要指定默认方式以外的方式时,需要实例化 Regex 类的实例。特别是在设置选项时。例如,要创建忽略大小写和模式空白区域的 Regex 实例,然后检索与该表达式匹配的集合,则应使用如下代码:

Regex re = new Regex(pattern, 
   RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
MatchCollection mc = re.Matches(inputString);

方法 说明 
Compiled
当在循环中执行许多匹配操作时使用此选项。这可以节省每一循环的分析表达式步骤。
 
Multiline
它与输入字符串中的行数没有关系。确切地说,它只修改 ^ 和 $ 的方式,以便匹配行开始 (BOL) 和行结尾 (EOL),而不是匹配整个输入字符串的开始和结尾。
 
IgnoreCase
使模式在匹配搜索字符串时忽略大小写。
 
IgnorePatternWhitespace
允许根据需要在模式中包括任意数量的空白区域,也支持使用 (?# 注释 #) 语法在模式中加入注释。
 
SingleLine
它与输入字符串中的行数没有关系。更确切地说,它将导致 .(句点)元字符匹配任意字符,而不是除 \n 之外的任意字符(默认情况)。
 
ms-help://MS.MSDNQTR.2003FEB.2052/cpref/html/frlrfSystemTextRegularExpressionsRegexMembersTopic.htm


samanthacsharp 发表于 >2006-1-26 14:36:55 保存该日志到本地 [全文] [评论] [引用] [推荐] [档案] [推给好友] [收藏到网摘]

 

2006-1-25
正则表达式

正则表达式 regular expression 
正则表达式 RegExp 
模式 pattern 
匹配 Match 
.NET命名空间: System.Text.RegularExpression 
 
补充: 
^\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 

 
利用正则表达式去除字串中重复的字符的算法程序: 

var s="abacabefgeeii" 
var s1=s.replace(/(.).*\1/g,"$1" 
var re=new RegExp("["+s1+"]","g" 
var s2=s.replace(re,"" 
alert(s1+s2) //结果为:abcefgi 
=============================== 
如果var s = "abacabefggeeii" 
结果就不对了,结果为:abeicfgg 
正则表达式的能力有限 

 
1.确认有效电子邮件格式 
下面的代码示例使用静态 Regex.IsMatch 方法验证一个字符串是否为有效电子邮件格式。如果字符串包含一个有效的电子邮件地址,则 IsValidEmail 方法返回 true,否则返回 false,但不采取其他任何操作。您可以使用 IsValidEmail,在应用程序将地址存储在数据库中或显示在 ASP.NET 页中之前,筛选出包含无效字符的电子邮件地址。 
[C#] 
bool IsValidEmail(string strIn) 

// Return true if strIn is in valid e-mail format. 
return Regex.IsMatch(strIn, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"



2.清理输入字符串 
下面的代码示例使用静态 Regex.Replace 方法从字符串中抽出无效字符。您可以使用这里定义的 CleanInput 方法,清除掉在接受用户输入的窗体的文本字段中输入的可能有害的字符。CleanInput 在清除掉除 @、-(连字符)和 .(句点)以外的所有非字母数字字符后返回一个字符串。 
[C#] 
String CleanInput(string strIn) 

// Replace invalid characters with empty strings. 
return Regex.Replace(strIn, @"[^\w\.@-]", ""



3.更改日期格式 
以下代码示例使用 Regex.Replace 方法来用 dd-mm-yy 的日期形式代替 mm/dd/yy 的日期形式。 
[C#] 
String MDYToDMY(String input) 

return Regex.Replace(input, 
"\\b(?<month>\\d{1,2})/(?<day>\\d{1,2})/(?<year>\\d{2,4})\\b", 
"${day}-${month}-${year}"

Regex 替换模式 
本示例说明如何在 Regex.Replace 的替换模式中使用命名的反向引用。其中,替换表达式 ${day} 插入由 (?<day>...) 组捕获的子字符串。 

有几种静态函数使您可以在使用正则表达式操作时无需创建显式正则表达式对象,而 Regex.Replace 函数正是其中之一。如果您不想保留编译的正则表达式,这将给您带来方便 


4.提取 URL 信息 
以下代码示例使用 Match.Result 来从 URL 提取协议和端口号。例如,“::URL::http://www.contoso.com:8080/letters/readme.html”将返回“http:8080”。  
[C#] 
String Extension(String url) 

Regex r = new Regex(@"^(?<proto>\w+)://[^/]+?(?<port>:\d+)?/", 
RegexOptions.Compiled); 
return r.Match(url).Result("${proto}${port}"


samanthacsharp 发表于 >2006-1-25 17:15:20 保存该日志到本地 [全文] [评论] [引用] [推荐] [档案] [推给好友] [收藏到网摘]

 

2006-1-25
正则表达式 API

正则表达式API
除了 ASP.NET 验证控件,在.NET 中使用正则表达式的大多数情况都要使用 System.Text.RegularExpressions 命名空间中发现的类。特别是那些您希望熟悉的主类 Regex、Match 和 MatchCollection。

顺便说一下,正则表达式缩写样式 regex 的发音究竟是 /reg-eks/ 还是 /rej-eks/,还有一些争议。本人倾向于后者,但两种发音都有专家赞同,所以选择哪个发音由您自己决定。

Regex 类有大量的方法和属性,如果您以前没有用过它,可能会感到无所适从。下面汇总了一些最常用的方法:

方法 说明 
Escape / Unescape
 字符串中的转义元字符,用作表达式中的文字。
 
IsMatch
 如果正则表达式在输入字符串中发现匹配,返回“Ture”。
 
Match
 如果在输入字符串中发现匹配,则返回匹配对象。
 
Matches
 如果在输入字符串中发现包含任何或全部匹配,则返回匹配集合对象。
 
Replace
 用给定的替换字符串替换输入字符串中的匹配。
 
Split
 将输入字符串拆分成用正则表达式匹配分开的数组元素时,返回数组字符串。
 

除了指定很多方法外,还有一些选项可以指定,通常在 Regex 对象构造函数中。由于这些选项是位屏蔽的一部分,或许可以同时指定这些选项(如,可以同时指定 Multiline 和 Singleline)。

方法 说明 
Compiled
 当在循环中执行许多匹配操作时使用此选项。这可以节省每一循环的分析表达式步骤。
 
Multiline
 它与输入字符串中的行数没有关系。确切地说,它只修改 ^ 和 $ 的方式,以便匹配行开始 (BOL) 和行结尾 (EOL),而不是匹配整个输入字符串的开始和结尾。
 
IgnoreCase
 使模式在匹配搜索字符串时忽略大小写。
 
IgnorePatternWhitespace
 允许根据需要在模式中包括任意数量的空白区域,也支持使用 (?# 注释 #) 语法在模式中加入注释。
 
SingleLine
 它与输入字符串中的行数没有关系。更确切地说,它将导致 .(句点)元字符匹配任意字符,而不是除 \n 之外的任意字符(默认情况)。
 

使用正则表达式常执行的操作包括:验证、匹配和替换。大多数情况下,可以使用 Regex 类的静态方法完成这些操作,不需要实例化 Regex 类本身。要执行验证,全部要做的就是必建或找到正确的表达式,然后使用 Regex 类的 IsMatch() 方法将表达式应用到输入字符串中。例如,下面的函数演示了如何使用正则表达式验证邮政编码:

private void ValidateZipButton_Click(object sender, System.EventArgs e)
{
   String ZipRegex = @"^\d{5}$";
   if(Regex.IsMatch(ZipTextBox.Text, ZipRegex))
   {
      ResultLabel.Text = "ZIP is valid!";
   }
   else
   {
      ResultLabel.Text = "ZIP is invalid!";
   }
}

类似的,可以使用静态 Replace() 方法将匹配替换为特定字符串,如下所示:
String newText = Regex.Replace(inputString, pattern, replacementText);
最后,可以使用如下代码遍历输入字符串的匹配集合:

private void MatchButton_Click(object sender, System.EventArgs e)
{
   MatchCollection matches = Regex.Matches(SearchStringTextBox.Text, 
MatchExpressionTextBox.Text);
   MatchCountLabel.Text = matches.Count.ToString();
   MatchesLabel.Text = "";
   foreach(Match match in matches)
   {
      MatchesLabel.Text += "Found" + match.ToString() + " at 
position " + match.Index + ".<br>";
   }
}

通常,在您需要指定默认方式以外的方式时,需要实例化 Regex 类的实例。特别是在设置选项时。例如,要创建忽略大小写和模式空白区域的 Regex 实例,然后检索与该表达式匹配的集合,则应使用如下代码:

Regex re = new Regex(pattern, 
   RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
MatchCollection mc = re.Matches(inputString);

本文的下载文件中包括这些示例的完整使用版本,与简单 ASP.NET 页中的一样。
posted @ 2006-09-27 11:39  随风而逝  阅读(1361)  评论(0编辑  收藏  举报