找回密码
 入住遨海湾
搜索
网站解决方案专享优惠-3折上云
查看: 955|回复: 1

ASP中正则表达式的应用[转自 动网先锋]

[复制链接]
发表于 2004-12-14 09:43:00 | 显示全部楼层 |阅读模式

登录后查才能浏览下载更多咨询,有问题联系QQ:3283999

您需要 登录 才可以下载或查看,没有账号?入住遨海湾

×
一、正则表达式概述 1 ?/ V- X! H) \  二、正则表达式在VBScript中的应用. z/ S; B2 o- A1 y2 l% d- Z   三、正则表达式在VavaScript中的应用 2 ~+ ^1 D6 W9 ]5 [: D: B# a6 L  四、示例 ) G9 i# V+ R! t! `  五、总结 # y' [' B/ z' S& C4 \ : V5 W2 N: u/ P0 x% `" j; k  一、正则表达式概述 / k: k# R+ Z- J7 f! t! e3 P. f) m   如果原来没有使用过正则表达式,那么可能对这个术语和概念会不太熟悉。不过,它们并不是您想象的那么新奇。 G4 k' e3 a7 t) N6 H   请回想一下在硬盘上是如何查找文件的。您肯定会使用 ? 和 * 字符来帮助查找您正寻找的文件。? 字符匹配文件名中的单个字符,而 * 则匹配一个或多个字符。一个如 'data?.dat' 的模式可以找到下述文件:data1.dat、data2.dat等等。如果使用 * 字符代替 ? 字符,则将扩大找到的文件数量。'data*.dat' 可以匹配下述所有文件名:data.dat、data1.dat、data12.dat等等,尽管这种搜索文件的方法肯定很有用,但也十分有限。? 和 * 通配符的有限能力可以使你对正则表达式能做什么有一个概念,不过正则表达式的功能更强大,也更灵活。2 k& _) h: f: Z1 [( U   在我们编写ASP程序时,经常会判断一个字符串的有效性,如;一个串是否是数字、是否是有效的Email地址等等。如果不使用正则表达式,那么判断的程序会很长,并且容易出错,如果使用正则表达式,这些判断就是一件很轻松的工作了。后面我们将介绍如何判断数字和Email地址的有效性。 ' ?: ~& p- }; U  在典型的搜索和替换操作中,必须提供要查找的确切文字。这种技术对于静态文本中的简单搜索和替换任务可能足够了,但是由于它缺乏灵活性,因此在搜索动态文本时就有困难了,甚至是不可能的。 * c. f8 m2 Z, B }, P6 p" C  使用正则表达式,能完成些什么事情呢? ; R+ }7 P! J9 P7 N( c  测试字符串的某个模式。例如,可以对一个输入字符串进行测试,看在该字符串是否存在一个电话号码模式或一个信用卡号码模式。这称为数据有效性验证。 ( e7 K" f; J6 O# c( X' D- h: A. P   替换文本。可以在文档中使用一个正则表达式来标识特定文字,然后可以全部将其删除,或者替换为别的文字。 7 K" d6 r8 d- T! W3 f' s' Y   根据模式匹配从字符串中提取一个子字符串。可以用来在文本或输入字段中查找特定文字。 7 b$ |1 k1 n* S% t  例如,如果需要搜索整个 web 站点来删除某些过时的材料并替换某些HTML 格式化标记,则可以使用正则表达式对每个文件进行测试,看在该文件中是否存在所要查找的材料或 HTML 格式化标记。用这个方法,就可以将受影响的文件范围缩小到包含要删除或更改的材料的那些文件。然后可以使用正则表达式来删除过时的材料,最后,可以再次使用正则表达式来查找并替换那些需要替换的标记。" t" {* H0 b8 ~   那么,正则表达式语法的语法是如何呢?: Z9 O* F) Q% W' K3 n- q   一个正则表达式就是由普通字符(例如字符 a 到 z)以及特殊字符(称为元字符)组成的文字模式。该模式描述在查找文字主体时待匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。: q7 _+ Z: F; G. W5 O* b3 e0 p   这里有一些可能会遇到的正则表达式示例: & b2 R- `6 N' E) Z. f  /^\[ \t]*$/ "^\[ \t]*$" 匹配一个空白行。 0 p- G9 C0 @, m+ M1 {   /\d{2}-\d{5}/ "\d{2}-\d{5}" 验证一个ID 号码是否由一个2位数字,一个连字符以及一个5位数字组成。 3 g/ f& y9 T' s, u9 e' V   /<(.*)>.*<\/\1>/ "<(.*)>.*<\/\1>" 匹配一个 HTML 标记。 . [8 F1 w2 T* S" i1 j+ h1 j4 U4 M2 I7 I: ]# w: q9 z& W7 s   二、正则表达式在VBScript中的应用 1 w+ |" \5 e. a8 l2 a; M4 @1 g  VBScript使用RegExp对象、Matches集合以及Match对象提供正则表达式支持功能。我们还是先看一个例子。0 T" r" U. h; J9 C ]+ J* o7 j % O# R3 e6 X) N& T- f/ x2 L) z <% 0 k$ {( F$ M' z/ Z Function RegExpTest(patrn, strng) # ~, r, ]) R' u* N+ Y Dim regEx, Match, Matches   '建立变量。 4 M" o/ ^& g# Q% S( t8 Q6 k$ t5 s Set regEx = New RegExp   '建立正则表达式。 1 }+ f6 q: Q2 Q( z regEx.Pattern = patrn  '设置模式。4 V. W- m: \7 W8 v& C& L# T regEx.IgnoreCase = True   '设置是否区分字符大小写。" J. Z, Y4 E" d1 G+ y! { regEx.Global = True   '设置全局可用性。 5 H# b/ Z& v1 T Set Matches = regEx.Execute(strng)  '执行搜索。; a& M& s- p) J1 r* V For Each Match in Matches  '遍历匹配集合。 5 {+ x8 V4 z( a) w4 O N$ H: y RetStr = RetStr & "Match found at position " ( d* L& H4 Y8 g, e RetStr = RetStr & Match.FirstIndex & ". Match Value is '"9 Z l$ ~, L. b9 n: s- I RetStr = RetStr & Match.Value & "'." & "<BR>"- O- p8 m5 N x- r Next ' U4 V j3 E3 B; r RegExpTest = RetStr/ N% q4 @6 i a End Function ) ?/ z; s0 S; w3 \9 r, E8 P response.write RegExpTest("[ij]s.", "IS1 Js2 IS3 is4")4 V! x) u% e! w6 S5 n %> ' y% D* c2 X% Y, m. E, N在这个例子中,我们查找字符串中有无is或者js这两个词,忽略大小写。运行的结果如下: " S2 P9 X" ~( a |1 ^7 e9 JMatch found at position 0. Match Value is 'IS1'. 1 s: {+ U! |4 n" p1 y% NMatch found at position 4. Match Value is 'Js2'. ( o( S g7 F* Z Y! j* G3 cMatch found at position 8. Match Value is 'IS3'.# ~- g' {5 ~+ h9 D" Q- D Match found at position 12. Match Value is 'is4'.& q) o1 k3 N9 t$ f5 f- D# m' ` 下面我们就介绍这三个对象和集合。/ ]. m- X5 i& ]! R) X   1、RegExp对象是最重要的一个对象,它有几个属性,其中: c3 g2 l3 `- m- {8 Q  ○Global 属性,设置或返回一个 Boolean 值,该值指明在整个搜索字符串时模式是全部匹配还是只匹配第一个。如果搜索应用于整个字符串,Global 属性的值为 True,否则其值为 False。默认的设置为 False。 ) S( e* a9 N; o0 m2 z7 j  ○IgnoreCase 属性,设置或返回一个Boolean值,指明模式搜索是否区分大小写。如果搜索是区分大小写的,则 IgnoreCase 属性为 False;否则为 True。缺省值为 False。 ! \- D5 Y3 D! G, I x  ○Pattern 属性,设置或返回被搜索的正则表达式模式。必选项。总是一个 RegExp 对象变量。4 |5 Y5 v2 K6 T, C   2、Match 对象 4 K0 U; O& s# K2 X* F9 }: E( [  匹配搜索的结果是存放在Match对象中,提供了对正则表达式匹配的只读属性的访问。 Match 对象只能通过 RegExp 对象的 Execute 方法来创建,该方法实际上返回了 Match 对象的集合。所有的 Match 对象属性都是只读的。在执行正则表达式时,可能产生零个或多个 Match 对象。每个 Match 对象提供了被正则表达式搜索找到的字符串的访问、字符串的长度,以及找到匹配的索引位置等。* \+ x% p7 b A   ○FirstIndex 属性,返回在搜索字符串中匹配的位置。FirstIndex 属性使用从零起算的偏移量,该偏移量是相对于搜索字符串的起始位置而言的。换言之,字符串中的第一个字符被标识为字符 01 w2 a4 f) A, [2 [3 d/ @   ○Length 属性,返回在字符串搜索中找到的匹配的长度。 " k1 o: @. i2 b% k7 [! B  ○Value 属性,返回在一个搜索字符串中找到的匹配的值或文本。% E5 i2 P7 b9 w   3、Matches 集合3 z5 v, T$ r9 O$ X   正则表达式 Match 对象的集合。Matches 集合中包含若干独立的 Match 对象,只能使用 RegExp 对象的 Execute 方法来创建之。与独立的 Match 对象属性相同,Matches `集合的一个属性是只读的。在执行正则表达式时,可能产生零个或多个 Match 对象。每个 Match 对象都提供了与正则表达式匹配的字符串的访问入口、字符串的长度,以及标识匹配位置的索引。 , t. |& H. @ k8 p! U  学习了这三个对象和集合,如何应用于字符串的判断和替换呢?regExp对象的三个方法正好解决了这个问题,它们是Replace方法、Test方法和Execute方法。+ g" }1 Z- q( g% K   1、Replace 方法 ) B+ _* L+ E9 N# w# S" S6 T k% a  替换在正则表达式查找中找到的文本。我们还是先看个例子:下面的例子说明了 Replace 方法的用法。) ~+ m V9 i/ |7 Y% J6 b, y 4 J6 V" p5 B; ^, S* N<%( x( T- T- f0 h, w; D' ]6 o7 H0 b" J Function ReplaceTest(patrn, replStr) / `+ P$ T; v5 O& l Dim regEx, str1 ' 建立变量。 ) }$ b9 [( L. r; ~& w str1 = "The quick brown fox jumped over the lazy dog." 5 i1 s/ L/ ^( r+ C Set regEx = New RegExp ' 建立正则表达式。 . d+ ~5 e! |, n; [1 P: g7 P8 Y regEx.Pattern = patrn ' 设置模式。 2 U6 d8 T& Q4 I! s; E' f- \- H8 y regEx.IgnoreCase = True ' 设置是否区分大小写。& X* y3 A" L+ D6 ?9 p: ]* J! i& } ReplaceTest = regEx.Replace(str1, replStr) ' 作替换。9 _! ]2 @5 B# |2 b7 D7 g% \. b End Function. }9 w1 A. R4 l7 J: U6 d2 v Response.write ReplaceTest("fox", "cat") & "<BR>" ' 将 'fox' 替换为 'cat'。; H: a2 [/ D a4 j2 a Response.write ReplaceTest("(\S+)(\s+)(\S+)", "$3$2$1") ' 交换词对.: a1 F9 I8 \8 x6 \2 h3 y2 x+ Y" t %>
遨海湾-心灵的港湾 www.aosea.com
 楼主| 发表于 2004-12-14 09:46:00 | 显示全部楼层
2、Test 方法4 v1 s- D* I8 G$ n6 D/ i- n1 n1 z   对指定的字符串执行一个正则表达式搜索,并返回一个 Boolean 值指示是否找到匹配的模式。正则表达式搜索的实际模式是通过RegExp对象的Pattern属性来设置的。RegExp.Global属性对Test方法没有影响。9 H+ `4 v$ u+ ?& ^- N   如果找到了匹配的模式,Test方法返回True;否则返回False。下面的代码说明了Test 方法的用法。7 h% h: v" X1 @* y* E8 F; H2 c! m <%& [% c/ M9 B w9 t Function RegExpTest(patrn, strng): B. i3 |0 p' x3 @/ j Dim regEx, retVal ' 建立变量。 ( G0 h) g' n8 k Set regEx = New RegExp ' 建立正则表达式。 4 A. o, M! R& G7 T& L' a$ j- W) ?! q regEx.Pattern = patrn ' 设置模式。) ^6 w! o- v) D regEx.IgnoreCase = False ' 设置是否区分大小写。* |8 Q& H% T2 E# W2 B$ Y% a1 b retVal = regEx.Test(strng) ' 执行搜索测试。1 V- X4 ~9 }- Z, Y! c3 B If retVal Then* v* ^1 P3 F: s7 M+ U: c1 Q RegExpTest = "找到一个或多个匹配。" 4 m; y+ u- H, i0 @ [ Else. w9 [ i* Z2 X3 ^! C; w* x RegExpTest = "未找到匹配。"( J* E* ^3 Y7 A+ b( {0 A9 {0 i. x W End If ( X" S4 w4 G5 [6 q8 x7 v& {6 O End Function / I7 @6 C# D& J- {8 A Response.write RegExpTest("is.", "IS1 is2 IS3 is4") % T7 n* k( o" }. W$ L% i%> # n! s* h0 c/ k; O  3、Execute 方法! D* a3 s) f% {. O! I3 O o* e   对指定的字符串执行正则表达式搜索。正则表达式搜索的设计模式是通过 RegExp 对象的 Pattern 来设置的。 4 X( V1 m# o# K' ]* b+ K  Execute 方法返回一个 Matches 集合,其中包含了在 string 中找到的每一个匹配的 Match 对象。如果未找到匹配,Execute 将返回空的 Matches 集合。; J. T- m8 K# f7 |- W8 E1 { ~   三、JavaScript中正则表达式的使用3 y- D$ e) Z9 ^" y z   在JavaScript 1.2版以后,JavaScript也支持正则表达式。 W' D6 @0 j! h- F  1、replace 5 t3 _* m% c0 F) z1 Y) U   replace在一个字符串中通过正则表达式查找替换相应的内容。replace并不改变原来的字符串,只是重新生成了一个新的字符串。如果需要执行全局查找或忽略大小写,那么在正则表达式的最后添加g和i。 % b N$ f/ l8 D! \- ]例: |. [" O. I( v. S2 C4 T7 w0 o, I7 B <SCRIPT>' c9 b. z4 c9 _' E re = /apples/gi; % e6 m2 s) }# \ str = "Apples are round, and apples are juicy.";! a8 u3 |" V' y2 d newstr=str.replace(re, "oranges"); ' U! }! @* z. e/ a document.write(newstr)( G8 [, {( o+ T0 T3 H </SCRIPT> ; @& w2 M/ N M结果是:"oranges are round, and oranges are juicy." 7 D# \2 p! T& |5 A 例: * w6 A( x8 d+ g: ?2 s B) x<SCRIPT>6 I! C( F2 @4 V s" p* p: l% U str = "Twas the night before Xmas...";0 \( Y" Q# S% @- C( ]8 M7 u2 J newstr=str.replace(/xmas/i, "Christmas");% w3 Y2 b, Q+ F0 g. e% K3 A document.write(newstr) 0 b* O2 M* p. m Q</SCRIPT> $ }2 Y2 _7 [1 z) c结果是:"Twas the night before Christmas..." ) i) P( D& J3 ^3 Z) j 例: 1 o' [7 ?) f3 Q U- h<SCRIPT>' J3 o0 g9 Y! b8 O h$ G. X re = /(\w+)\s(\w+)/;str = "John Smith";6 G; @* T5 W$ w1 X; s5 W newstr = str.replace(re, "$2, $1"); , R' a; G0 U5 t" B e document.write(newstr) 6 X$ j- p+ U# Y2 S8 s( y5 v</SCRIPT>$ ?+ K7 E# A$ E) l# Q 结果是:"Smith, John". 1 }4 ]+ C- n/ U: ~6 ~7 N& |  2、search 6 ?- |1 X3 `/ ?5 }! }search通过正则表达式查找相应的字符串,只是判断有无匹配的字符串。如果查找成功,search返回匹配串的位置,否则返回-1。 ! }4 |9 o3 n7 U8 }2 L8 u    search(regexp) 7 z! z8 h8 U2 ]+ j+ z+ ?9 t. W<SCRIPT>, ?2 ~! E3 e& ?3 O function testinput(re, str){6 u' A( K, j$ y7 Y8 e L% }% \: @ if (str.search(re) != -1)+ ~+ `9 \9 w, Z/ T( a, { midstring = " contains "; 4 M' y( P! {; G$ ~% r0 Z else" y8 g( P1 @7 s; L. B midstring = " does not contain ";/ I* u4 c) d: S- o1 G) V0 R document.write (str + midstring + re.source);9 Y" B% z9 F' A8 J$ P3 }2 W! j } + F4 g6 v$ d5 p% ]$ x% I) I8 `7 q testinput(/^[1-9]/i,"123")' C$ @+ i" O% w) ~ </SCRIPT> 1 N! [6 i' o/ l  3、match / K7 e: O) M: k$ _ y  match方法执行全局查找,查找结果存放在一个数组里。! M0 u# {( ` u( |8 G 例一: * b) Q( T, W5 o V <SCRIPT> 7 p: C& y; o8 t, v str = "For more information, see Chapter 3.4.5.1";# T7 ^- e6 W3 `+ t( x/ U7 _ re = /(chapter \d+(\.\d)*)/i; 7 L9 p6 b, y$ C' Q found = str.match(re); 7 ^. ?' K4 i: I document.write(found); * j# Q4 K- I- t+ B</SCRIPT>, B* b/ W E8 |1 z2 R/ D/ T7 ` 显示结果:Chapter 3.4.5.1,Chapter 3.4.5.1,.1 ; L! v1 W6 B4 ?: `4 a9 ?例二:0 } C t1 m R, Q* @ <SCRIPT> * Z" ~2 p# g! Q5 ]( _. I str = "abcDdcba"; 1 u6 v2 R& @0 H j- Q) ?2 w- r newArray = str.match(/d/gi); . \9 X, d/ o4 P- i. \ document.write(newArray); ) V- x# x7 j$ D+ E </SCRIPT> 7 r! Y7 x" N3 V/ W7 b* ~5 O显示结果D, d. - ^8 H/ a, ~4 K& l  四、示例 0 G; k- h% _, [1 、判断数字的正确性8 c; O: s l+ s! X4 {3 @2 v6 Q1 F <%@ Language=VBScript %> : F/ d7 L9 j3 V$ E0 R% y<script language="javascript" runat="server">* S% O2 B3 @5 V) w: t function isNumeric(strNumber) { : {) _2 n2 w+ ~* c h5 _ return (strNumber.search(/^(-|\+)?\d+(\.\d+)?$/) != -1); % |/ d! A" G3 W4 m3 j% C- a* F } ; B2 B# T' {! y- l0 f# A* B0 W+ D function isUnsignedNumeric(strNumber) { 2 ?+ M" S0 U" c, J return (strNumber.search(/^\d+(\.\d+)?$/) != -1); 4 O1 j8 T9 M: E& ^ a) K3 n } ; r$ z, E' \" d4 u" R8 Q3 v1 B function isInteger(strInteger) {) Z- S0 ]- E$ X5 e$ ~3 j8 b return (strInteger.search(/^(-|\+)?\d+$/) != -1); $ v; h8 n, P* P! r } / O e% z$ v9 ?% @7 T function isUnsignedInteger(strInteger) { 7 l8 A$ S4 f/ i return (strInteger.search(/^\d+$/) != -1); 5 B, [2 q9 f0 [: i }2 G* @0 m3 R2 }% ?& @! ? </script> : M* {7 D" s' i9 ?/ N' N$ p1 J/ I<HTML> 7 \3 R0 B" d. h9 E# g" l& ^; Q" T<BODY> ) a4 k% O; Y0 L3 F; u<b>判断数字的正确性</b>, R! |; H% o; a9 J4 y! N <% 6 b/ a6 f! B; k, F+ o Dim strTemp, [& _ c$ h! C* t4 b" T8 Y strTemp = CStr(Request.Form("inputstring")) 7 C7 @1 Z! ^) W" c If strTemp = "" Then strTemp = "0"0 Q: ^( @5 M z2 ~! n6 Y# G/ b4 E %> ; o# u2 d2 w/ |<TABLE BORDER="1" CELLPADDING="4" CELLSPACING="2"> / K! i4 y2 `' N8 `2 |' I <TR>+ \5 I0 D5 Y! G0 A x) p <TD ALIGN="right"><B>原始字符串</B></TD>- a+ W! v9 b; T. V+ X/ z8 |2 I <TD><%= strTemp %></TD> # I0 d* g8 ], V( x </TR>; A6 K, r* _6 \9 N. N" U8 p& H <TR>( E2 n P. B; o+ O8 M <TD ALIGN="right"><B>数字</B></TD>0 M3 d/ ~& K6 V, `0 Y! D <TD><%=isNumeric(strTemp)%></TD>0 t/ [- I6 d. l1 S! N& O5 ^7 F </TR>5 Y* L/ Q5 s, i8 L+ Y <TR> " `) ^1 k. K6 m q6 p# _; i% w+ { <TD ALIGN="right"><B>非负数字</B></TD> 6 F4 K6 ~$ a: H/ \6 F. q6 a <TD><%=isUnsignedNumeric(strTemp)%></TD>9 Y$ R4 C& n+ |5 v# b7 S. P </TR>$ ]; \9 e3 o0 s# Z' O4 F8 g <TR>8 q1 x6 @5 k3 B7 Z/ U4 \9 @ <TD ALIGN="right"><B>整数</B></TD>0 k* p( Q9 }0 B- [! { <TD><%=isInteger(strTemp)%></TD>$ ~8 S1 W1 [/ g4 u7 f) k </TR>% Y' L/ p3 k Q# d0 |) [% w <TR> $ V2 l% K) B/ M' M, L' Z- [6 F# A4 ? <TD ALIGN="right"><B>非负整数()</B></TD> 8 O( \/ {7 @5 C+ t <TD><%=isUnsignedInteger(strTemp)%></TD> - h3 X, |0 }# k" V% m6 X7 z </TR>) K/ X3 e7 E3 v8 }* _+ U8 i </TABLE>, a* Y5 _ n' {4 A" ] A3 S, Z7 ` <FORM ACTION="<%=Request.ServerVariables("SCRIPT_NAME")%>" METHOD="post">5 o. q3 Z- x; e) C 请输入一个数字:<BR> 3 s! b1 T( u6 \: @* d' z% ]( ] <INPUT TYPE="text" NAME="inputstring" SIZE="50"></INPUT><BR> . Y5 f9 w L A* R <INPUT TYPE="submit" Value="提交"></INPUT><BR>6 a. ?* {! Y: o y0 |/ q </FORM>2 c; c6 k* k" d) b% b! r </BODY> + v. A, c9 C& D; N</HTML># m& n. j) h! p* R, ^1 A" { 2、判断Email地址的正确性, I# M: q9 d7 j6 Y. ? ' j! b1 S& n9 `0 \7 w N <%) o. n9 g2 _% G9 i9 N1 y Function isemail(strng)1 j4 g& ^9 ^, @2 ]- B' N isemail = false & x# F% t" k( u- [1 k* U8 h6 N1 s Dim regEx, Match$ A3 y' C. {5 y# H6 P i. U. v Set regEx = New RegExp( x$ C2 M8 A6 L8 E3 c, ? regEx.Pattern = "^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$"8 b0 I& N+ X1 F' ^, Y) ] regEx.IgnoreCase = True. v1 v4 Y" k9 U1 [, ~7 j Set Match = regEx.Execute(strng) m5 b4 f7 |0 f \$ n, ^ if match.count then isemail= true/ m a3 @% @+ @$ v1 a6 t# V, _. ] End Function & H4 i, }; u" a! v* }" ?%>9 _6 g( E# {% e1 m   五、总结( ~8 L9 _$ r4 G% Z2 `5 Y2 N: V   上面我们介绍了正则表达式的基本概念,以及在VBScript和JavaScript中如何使用正则表达式,同时,通过一些实例让大家有了感性的认识。正则表达式的应用范围很广,能为大家解决很多实际中的问题。本文介绍的内容只是一些初步的知识,还有很多语法规则需要大家继续学习,在实践中发现问题,解决问题。
遨海湾-心灵的港湾 www.aosea.com
您需要登录后才可以回帖 登录 | 入住遨海湾

本版积分规则

网站解决方案专享优惠-3折上云

QQ|手机版|小黑屋|遨海湾超级社区

GMT+8, 2025-1-19 02:53

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表