碧海潮声大学生网
标题:
〖原创〗.NET中正则表达式应用一些体会
[打印本页]
作者:
蓝鲸
时间:
2005-11-18 23:20
标题:
〖原创〗.NET中正则表达式应用一些体会
前些想自己写个.net的论坛,却发现些问题,其中就是这UBBCODE,以前用ASP写的,只知引用,不是这代码意思。但现在ASP代码移到C#或VB中就有问题了,主要是不理解这正则表达式。这几天就好好研究了一下,只懂了些大概。
看了以后,才觉得这表达式真非常有用,特别是验正一些如日期,URL,Email或输入等,特别管用。
如日期格式:1980/12/18,12/18/1980,1980-12-18,1980年12月18,1980-2-8,
1980-02-08,一大堆格式,如果要验证,以前觉很困难,因为输入不要指望别人按你设想的格式输入,他们很可能会以其中之一的格式验证。其中还要考虑到他们的日期格式是错误的如1980-2-31等。用正则表达式就可解决了。
日期格式代码在家里,很快我会发上来,但觉代码有些多,有兴趣的朋友可以自制一个。
作者:
蓝鲸
时间:
2005-11-18 23:21
下面试了个例子,较简单,但需要了解一下正则表达式。
这里对表达式不想作教程了,VS.NET联机帮助已经非常好了。
如商品开票中有票号,格式很多,如SB0001890,123-890-899007,A01BB000898等,如果新票要在数字位上加1变成SB0001891,123-890-899008,A01BB000899,以前很可以会用法读取最后一位非数字位。用正则表达式,可以轻易把SB0001890分成"SB"和"0001890,接下去就省力了。
/// <summary>
/// 使原来的编号的数字位加1
/// </summary>
public string GetBillID(string strID)
{
string headStr; // 头字符串
string digitalStr; // 后位的数字字符串
string maxStr = ""; // 数字位的最大数字
string FormatStr = ""; // 格式化字符串
int newStr;
// 用正则函数去掉头字符串
digitalStr = Regex.Replace(strID, @"^\w*\D+", "");
// 取得头字符串
headStr = Regex.Replace(strID, @"\d*$", "");
// 如果后位没有数字,则返回空串
if (digitalStr == "")
{
return "";
}
// 取得最大数字和格式化字符串
for (int i = 1; i <= digitalStr.Length; i++)
{
maxStr += "9";
FormatStr += "0";
}
// 如果数字字串和最大数字相同,则返回不能再加的字串
if (digitalStr == maxStr)
{
return "MAX";
}
// 取得格式化字符串
newStr = Convert.ToInt32(digitalStr) + 1;
return headStr + newStr.ToString(FormatStr);
}
解释一下
@"^\w*\D+":
^ 表示靠最前
\w 表示任何字符 * 表示0个以上该字符的重复出现
\D 表示非数字字符 + 表示1个以上该字符的重复出现
@"\d*$":
\d 表示数字字符(注意与\D区别) * 表示0个以上该字符的重复出现
$ 必须靠未尾
作者:
蓝鲸
时间:
2005-11-18 23:21
/// <summary>
/// 检验Email字符串格式是否正确
/// </summary>
public bool IsEmailFormat(string strEmail)
{
return Regex.IsMatch(strEmail, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
}
是不是有些怕了, ;)但一定要有耐心,这代码已验证了,如果熟悉ASP,可以改一下的。
最近不太用ASP了,有些不常的用法有些忘了,所以就不写ASP的了,但如果语法熟悉一些的话,换一下不是问题,可参看UBBCode用法。
作者:
蓝鲸
时间:
2005-11-18 23:22
/// <summary>
/// 检验日期格式是否正确
/// </summary>
public string IsDateFormat(string strDate)
{
Regex r1 = new Regex(@"^(?<year>[1-9][0-9]{0,3})/(?<month>[0-9]{1,2})/(?<day>[0-9]{1,2})$");
Regex r2 = new Regex(@"^(?<year>[1-9][0-9]{0,3})-(?<month>[0-9]{1,2})-(?<day>[0-9]{1,2})$");
Regex r3 = new Regex(@"^(?<year>[1-9][0-9]{0,3})年(?<month>[0-9]{1,2})月(?<day>[0-9]{1,2})日$");
Regex r4 = new Regex(@"^(?<month>[0-9]{1,2})/(?<day>[0-9]{1,2})/(?<year>[1-9][0-9]{0,3})$");
// 取得日期的年,月,日
string year, month, date;
if(Regex.IsMatch(strDate,@"^(?<month>[0-9]{1,2})/(?<day>[0-9]{1,2})/(?<year>[1-9][0-9]{3})$"))
{
year = r4.Match(strDate).Result("${year}");
month = r4.Match(strDate).Result("${month}");
date = r4.Match(strDate).Result("${day}");
}
else if (Regex.IsMatch(strDate,@"^(?<year>[1-9][0-9]{0,3})/(?<month>[0-9]{1,2})/(?<day>[0-9]{1,2})$"))
{
year = r1.Match(strDate).Result("${year}");
month = r1.Match(strDate).Result("${month}");
date = r1.Match(strDate).Result("${day}");
}
else if(Regex.IsMatch(strDate,@"^(?<year>[1-9][0-9]{0,3})-(?<month>[0-9]{1,2})-(?<day>[0-9]{1,2})$"))
{
year = r2.Match(strDate).Result("${year}");
month = r2.Match(strDate).Result("${month}");
date = r2.Match(strDate).Result("${day}");
}
else if(Regex.IsMatch(strDate,@"^(?<year>[1-9][0-9]{0,3})年(?<month>[0-9]{1,2})月(?<day>[0-9]{1,2})日$"))
{
year = r3.Match(strDate).Result("${year}");
month = r3.Match(strDate).Result("${month}");
date = r3.Match(strDate).Result("${day}");
}
else
{
return "error";
}
// 最后检查日期的正确性
try
{
System.DateTime dt = new DateTime(Convert.ToInt32(year), Convert.ToInt32(month), Convert.ToInt32(date));
return dt.ToString("yyyy-MM-dd");
}
catch
{
return "error";
}
}
正则表达式,初看就让人生畏,只要坚持 :rolleyes:
另外还是觉本代码不是很完美,代码有些多,但一时也想不到好的方法。
最后一段new DateTime的方法,是.net固有的方法,尝试建立日期格式,如能建立,说明输入是正确的,不能就返回"ERROR"。
;)当然,你也可以用自己方法去验证年份正确性,如2月29日是否正确等问题。但我是不会再去做这样的事了,别人已经做得很完美了,就省下这时间去做些更有意义的事了。
欢迎光临 碧海潮声大学生网 (http://www.zjoubbs.com/)
Powered by Discuz! X3.2