正则式表达式的实用替换功能

在逛CSDN时发现一个非常实用的正则表达式问题.
采用正则表达替换xml标签的.
原来这样
    <ab> 45434 </ab>
    <dd> 34324 </dd>
    <dr   />
    <vv> 34324这里有换行
</vv>

替换成这样 
    <data> 45434 </data>
    <data> 34324 </data>
    <data> </data>
    <data> 34324这里有换行
</data> 

首先我们观察特征
 1.把<>\</>标签内的标签值替换为data;
 2.把</>标签内的标签值替换为data;

一下子我们就能想到的就是首先匹配到其所有的标签,然后把里面的标签全部替换为data
也就是这样的表达式.
(</?)[^>]+?(/?>)
去取得其所有的标签前缀和后缀,进行替换.即
$1data$2
完整的C#代码就为
string content = " <ab> 45434 </ab>     <dd> 34324 </dd>     <dr   />     <vv> 34324这里有换行 </vv> ";
string result=Regex.Replace(content,"(</?)[^>]+?(/?>)","$1data$2");
结果为
<data> 45434 </data> 
    
<data> 34324 </data> 
    
<data/> 
    
<data> 34324这里有换行 
</data> 


仔细一看,还有一点问题.那就是我们要求,当其标签为空标签时,即<a  />时,要将其替换为<data></data>,并不是简单的替换成为<data/>这种形式.看来还得修改.
但看样子正式表达式已经没有什么真可以改进的的了.至少说简单的修改能实现方案那是不行了.
不行就不行吧,与其弄的那样复杂,不如偷偷懒...我可以标准的懒人....
把那种情况分开进行处理
即单独进匹配那个标签内容为空的标签进行单独处理.
其实很容易就能得出其空标签的标志.它都是以/>标记结束的
所以匹配其空标签的正则表达式就为

<[^>]+?/>

具体的C#代码则为

string content = " <ab> 45434 </ab>     <dd> 34324 </dd>     <dr   />     <vv> 34324这里有换行 </vv> ";
string result = Regex.Replace(content, "<[^>]+?/>""<data></data>");

需求完成.先对其内容的空行进行替换,再对其它的标签进行替换.完成.
完成是完成了,不过还是有一点点问题,这种情况下我们将要去匹配替换两次,无论从效率还是编辑思路设计上都不是很好的.所以还得寻找更好的出路.

其实我们前面都提到了.那就是空标签就有内容标签的区别就是一个是以>结尾,而另一个是以/>结尾.
有了这个特征,程序就非常好处理了哈.就分别对匹配的item项的结尾进行判断,再根据判断替换相应的值.
实现这一功能,C#提供了一个非常好用的方法

Regex.Replace 方法 (String, String, MatchEvaluator)
在指定的输入字符串内,使用 MatchEvaluator 委托返回的字符串替换与指定正则表达式匹配的所有字符串。

命名空间: System.Text.RegularExpressions
程序集: System(在 system.dll 中)

public static string Replace (
    string input,
    string pattern,
    MatchEvaluator evaluator
)

参数

input

要搜索匹配项的字符串。

pattern

要匹配的正则表达式模式。

evaluator

一个自定义方法,它检查每个匹配项,并返回原始匹配字符串或替换字符串。

返回值

一个与输入字符串基本相同的新字符串,唯一的差别在于,其中的每个匹配字符串已被替换字符串代替。
备注

pattern 参数由通过符号描述要匹配的字符串的各种正则表达式语言元素组成。有关正则表达式的更多信息,请参见 .NET Framework 正则表达式正则表达式语言元素

evaluator 参数是您定义的用于检查每个匹配项的自定义方法的委托。您的自定义方法将返回替换了匹配输入的字符串。

说做就做.首先我们得修改我们的表达式.并把我们需要的字符尾字符串进行分组以备使用:

<(/?)[^>]+?(/?>)

好了,接下来的就全部交给程序处理了:
全部详细C#代码如下

string content = " <ab> 45434 </ab>     <dd> 34324 </dd>     <dr   />     <vv> 34324这里有换行 </vv> ";
string result = Regex.Replace(content, "<(/?)[^>]+?(/?>)", metaEvaluator);


private string metaEvaluator(Match item)
{

   
if (item.Groups[1].Value==""&&item.Groups[2].Value == ">")
       
return "<data>";
   
else if (item.Groups[1].Value == "/"&& item.Groups[2].Value == ">")
       
return "</data>";
   
else if (item.Groups[2].Value == "/>")
       
return "<data></data>";

   
else     return item.Value;
                        
}


问题解决.不过肯定还有很多需要改进的地方.

原文地址:https://www.cnblogs.com/symbol441/p/976993.html