在VS 2012中使用正则表达式

摘要:在VS 2012编辑器中使用正则表达式,可以有效提高开发效率。

一、这个帖子说的啥?

现在要说的是正则表达式。我们不去抠它的定义,也先不管那些严格而且琐碎的格式,而是看看怎么用。

大体来说,在.NET环境中进行开发时,有两个地方会用到正则表达式,一是用VS 2012进行编辑时,可以利用正则表达式进行查找和替换;二是代码中可以利用.NET提供的API,使用正则表达式的功能。

本文中说说第一种场景。我们通过几个例子看看怎么用正则表达式。

二、怎么查找包含回车换行的内容?

看下面的代码片段:

anObjectWithLongName.MethodAlsoWithLongName(
1, "blabla",...);


现在想要查找第一个参数为1时调用函数MethodAlsoWithLongName的地方。而由于对象名字和函数名字都太长,参数跑到了另外一行:和函数名不在一行上。

如果用Word,我们可以使用特殊字符^P,但VS 2012没有^P这样的特殊字符。怎么办呢?这时可以使用正则表达式。

首先按下Ctrl+Shift+F,表示在文件中查找,操作界面如下图所示:

首先选中“使用正则表达式”,然后在查找内容中输入:

MethodAlsoWithLongName\(\r\n1,

其中 MethodAlsoWithLongName 是我们要查找的函数名,1是要查找的参数,神奇的地方在于其中的\r\n,这在正则表达式中代表回车换行,相当于Word中的特殊字符^P。

另外注意其中的左括号前面加了反斜杠,这是因为左括号是正则表达式中的运算符,当我们真的需要左括号时,在前面加上反斜杠进行转义。

三、怎么查找符合指定格式的内容?

上面的例子中,\r\n是正则表达式的特殊字符,小括号是正则表达式的运算符,这些都属于正则表达式的基本知识。要使用正则表达式,还不得不掌握它们。好在MSDN中有详细介绍,网上也很容易查到。

我们继续举例子。话说有人写了这样的代码:

DataTable table = ...;
DataRow row = table.Rows[0];
...
string desc = row["desc"].ToString();
string name = row["name"].ToString();
string userId = row["id"].ToString();
...

我们对这样的代码不放心,因为row[colName]可能会返回空值,这时调用ToString()会引发空指针异常。我们想看看有多少处这样调用。(顺便说一下,我认为应当尽量少用DataTable,只在必要的地方才用它,例如数据库等的外部接口交互,在程序内部要设法避免。这属于结构化思路上的问题,以后再专门讨论。)

那么,我们的查询条件中,row[""].ToString()是固定的,但引号内的内容是不确定的。

这时仍使用正则表达式进行查找。操作和上个例子类似,只是查找条件不同,这一次是:

row\[".*"\]\.ToString\(\)
其中的固定部分是row[""].ToString(),但由于[, ], ., (, )都是正则表达式的运算符,因此,都做了转义。

注意其中的红色粗体部分:.*,.表示任意字符,*表示任意多个,没有也符合。

四、怎么用正则表达式进行替换

继续上面的例子,我们总是不放心那样的做法,要做判空处理:列值不空的时候,才转换为字符串。对每次调用都这样处理,显然很繁琐。自然的做法是提取一个函数:

public static class Utils
{
    public static string GetString(this DataRow row, string columnName)
    {
        return row.IsNull(columnName) ? string.Empty : row[columnName].ToString();
    }
}

这样上面的三行可以修改成:

...
string desc = row.GetString("desc");
string name = row.GetString("name");
string userId = row.GetString("id");
...

如果这样的调用很少,例如,只有这么三行,那么手工修改也就是了。但是如果很多,比如有几十上百处,一行行修改会让人崩溃。这时,正则表达式又可以派上用场了。

在使用正则表达式替换时,我们要清楚三个方面的内容:

 

1、替换的固定部分和可变部分

将 string desc = row["desc"].ToString(); 替换为 string desc = row.GetString("desc"); ,其中的row、前后两个desc是可变部分,其余是固定部分。其中固定部分就用原来的内容,可变部分要用.*那样的通配符。

查找的内容就是:string .* = .*\[".*"\]\.ToString\(\);

 

2、怎么提取原文中的可变部分

原文中的desc、row等内容还要用到,因此,需要从原文中提取出来,放到目标字符串中。怎么提取?这要用到正则表达式的“分组(Grouping)”概念(我现在也没有搞清楚为啥这么叫),将内容放到一个组中,就可以提取了。

在我们的例子中,所有可变内容都是需要的,因此,把它们都放到分组中。这样,查找的内容就变成了:string (.*) = (.*)\["(.*)"\]\.ToString\(\);

 

3、在目标字符串中怎么引用原文的可变部分

可以用分组序号引用,编号从1开始,用$加上序号,表示要获得分组的内容。上例中,$1表示变量名(如第一个desc),$2表示变量row,$3表示列名(第二个desc)。

这样,替换的目标字符串就是 string $1 = $2.GetString("$3");

 

替换的界面是这个样子的:

五、总结

没啥好总结的,利用正则表达式,就是可以提高效率。将几十、上百次重复劳动这样的体力活(真要做起来,多么苦逼啊~),改为脑力劳动,几下搞定!

 

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页