正则表达式替换和不包含指定字符串

需求

展示一段文字,段落中有些特殊标记的人名、刊名等,格式大体是:“(作者《刊名》其他)”,某个字段可以为空,比如作者为空。

那么对应的正则大体是这样的   ‘\((.*?)《(.*?)》.*?\)‘

最终的效果是 “(<a>作者</a>《<a>刊名</a>》其他)”

第一版

 1 class Program
 2     {
 3         static string str = @"<p>[例]当夫广州之首难,武汉兴师,革命精神,震铄一世。(《东方杂志》1912年第9卷第1号)|欲去此不平等与压制,继政治革命而谋社会革命者,社会主义是也。(《青年杂志》1915年第1卷第1号)|俄、德等国的劳工社会,首先看破他们的野心,不惜在大战的时候,起了社会革命,防遏这资本家政府的战争。(李大钊《庶民的胜利》1918年)|近年来文学革命的运动渐见功效,除了几个讲“纲常名教”的经学家。(周作人《思想革命》1919年)</p><p>[按] “革命”本指实施变革以应天命。“革命”现在经常指各个领域的新的改革,推动事物发生根本变革,引起事物从旧质变为新质的飞跃。<p>";
 4
 5         static string pattern = @"\((?<author>[^<>]*?)《(?<bookname>[^<>]*?)》.*?\)";
 6
 7         static void Main(string[] args)
 8         {
 9             Regex regex = new Regex(pattern);
10             while (regex.IsMatch(str))
11             {
12                 Match match = regex.Match(str);
13
14                 string author = match.Groups["author"].Value;
15                 string bookname = match.Groups["bookname"].Value;
16                 if (author + "" != "")
17                 {
18                    str = str.Replace(author, string.Format("<a href=‘#‘>{0}</a>", author));
19                 }
20                 if (bookname + "" != "")
21                 {
22                     str = str.Replace(bookname, string.Format("<a href=‘#‘>{0}</a>", bookname));
23                 }
24             }
25             Console.WriteLine(str);
26         }
27     }

这里使用了命名分组的匹配方式,之前有一篇写过相关东西,点击正则表达式分组小记查看

static string pattern = @"\((?<author>[^<>]*?)《(?<bookname>[^<>]*?)》.*?\)"; 

获取作者、刊名信息时,排除标签(‘<’和‘>’),效果还是可以的。

<p>[例]当夫广州之首难,武汉兴师,革命精神,震铄一世。(《<a href=‘#‘>东方杂志</a>
》1912年第9卷第1号)|欲去此不平等与压制,继政治革命而谋社会革命者,社会主义是也。(
《<a href=‘#‘>青年杂志</a>》1915年第1卷第1号)|俄、德等国的劳工社会,首先看破他们
的野心,不惜在大战的时候,起了社会革命,防遏这资本家政府的战争。(<a href=‘#‘>李大钊
</a>《<a href=‘#‘>庶民的胜利</a>》1918年)|近年来文学革命的运动渐见功效,除了几个
讲“纲常名教”的经学家。(<a href=‘#‘>周作人</a>《<a href=‘#‘>思想革命</a>》1919
年)</p><p>[按] “革命”本指实施变革以应天命。“革命”现在经常指各个领域的新的改
革,推动事物发生根本变革,引起事物从旧质变为新质的飞跃。<p>

当然没必要这样一次次循环替换,因为正则表达式替换可以一次帮你搞定。

至于这样做的目的,可以把不符合该正则表达式的作者名或者书名的内容一起替换为链接。而且最重要的是,可以针对每一次匹配值,可以做不同的处理。

比如通过匹配的作者或者书名再去数据库查找匹配的作者(或书名)的介绍(或者ID),然后添加到a标签的链接内(例如<a href=‘这里的链接是东方杂志的ID‘>东方杂志</a>)

再比如为空的匹配组,我们可以跳过不进行替换,下边的正则表达式替换版本,便无法做到这点了。

正则表达式替换版本

 1 class Program
 2     {
 3         static string str = @"<p>[例]当夫广州之首难,武汉兴师,革命精神,震铄一世。(《东方杂志》1912年第9卷第1号)|欲去此不平等与压制,继政治革命而谋社会革命者,社会主义是也。(《青年杂志》1915年第1卷第1号)|俄、德等国的劳工社会,首先看破他们的野心,不惜在大战的时候,起了社会革命,防遏这资本家政府的战争。(李大钊《庶民的胜利》1918年)|近年来文学革命的运动渐见功效,除了几个讲“纲常名教”的经学家。(周作人《思想革命》1919年)</p><p>[按] “革命”本指实施变革以应天命。“革命”现在经常指各个领域的新的改革,推动事物发生根本变革,引起事物从旧质变为新质的飞跃。<p>";
 4
 5         static string pattern = @"\((?<author>[^<>]*?)《(?<bookname>[^<>]*?)》(?<other>.*?)\)";  6
 7         static void Main(string[] args)
 8         {
 9             str = Regex.Replace(str, pattern, "(<a href=‘#‘>$1</a>《<a href=‘#‘>$2</a>》$3)");
10             Console.WriteLine(str);
11         }
12     }

最后的效果如下,也还不错。

<p>[例]当夫广州之首难,武汉兴师,革命精神,震铄一世。(<a href=‘#‘></a>《<a href=‘
#‘>东方杂志</a>》1912年第9卷第1号)|欲去此不平等与压制,继政治革命而谋社会革命者,
社会主义是也。(<a href=‘#‘></a>《<a href=‘#‘>青年杂志</a>》1915年第1卷第1号)|俄
、德等国的劳工社会,首先看破他们的野心,不惜在大战的时候,起了社会革命,防遏这资本家
政府的战争。(<a href=‘#‘>李大钊</a>《<a href=‘#‘>庶民的胜利</a>》1918年)|近年来
文学革命的运动渐见功效,除了几个讲“纲常名教”的经学家。(<a href=‘#‘>周作人</a>《
<a href=‘#‘>思想革命</a>》1919年)</p><p>[按] “革命”本指实施变革以应天命。“革
命”现在经常指各个领域的新的改革,推动事物发生根本变革,引起事物从旧质变为新质的飞
跃。<p>

这里用到了$n的东东,也是现查现用。

我理解的很简单,正则中使用了分组,而$n就是对应每个分组的匹配值,$0是整个正则匹配的结果,$1$2……是每个分组按前后顺序的匹配结果。

结果中标蓝的内容印证了为空匹配组也被替换的结果。

第二版

到目前为止,我们的程序没啥问题,但是数据是变化。看下边这个实例

 1 class Program
 2     {
 3         static string str = @"<p>[例]当夫广州之首难,武汉兴师,革命精神,震铄一世。(《东方杂志》1912年第9卷第1号)|欲去此不平等与压制,继政治革命而谋社会革命者,社会主义是也。(《青年杂志》1915年第1卷第1号)|俄、德等国的劳工社会,首先看破他们的野心,不惜在大战的时候,起了社会革命,防遏这资本家政府的战争。(李大钊《庶民的<font color=‘red‘>胜利</font>》1918年)|近年来文学革命的运动渐见功效,除了几个讲“纲常名教”的经学家。(周作人《思想革命》1919年)</p><p>[按] “革命”本指实施变革以应天命。“革命”现在经常指各个领域的新的改革,推动事物发生根本变革,引起事物从旧质变为新质的飞跃。<p>";
 4
 5         static string pattern = @"\((?<author>[^<>]*?)《(?<bookname>[^<>]*?)》(?<other>.*?)\)";
 6
 7         static void Main(string[] args)
 8         {
 9             str = Regex.Replace(str, pattern, "(<a href=‘#‘>$1</a>《<a href=‘#‘>$2</a>》$3)");
10             Console.WriteLine(str);
11         }
12
13     }

结果如下

<p>[例]当夫广州之首难,武汉兴师,革命精神,震铄一世。(<a href=‘#‘></a>《<a href=‘
#‘>东方杂志</a>》1912年第9卷第1号)|欲去此不平等与压制,继政治革命而谋社会革命者,
社会主义是也。(<a href=‘#‘></a>《<a href=‘#‘>青年杂志</a>》1915年第1卷第1号)|俄
、德等国的劳工社会,首先看破他们的野心,不惜在大战的时候,起了社会革命,防遏这资本家
政府的战争。(李大钊《庶民的<font color=‘red‘>胜利</font>》1918年)|近年来文学革
命的运动渐见功效,除了几个讲“纲常名教”的经学家。(<a href=‘#‘>周作人</a>《<a hre
f=‘#‘>思想革命</a>》1919年)</p><p>[按] “革命”本指实施变革以应天命。“革命”现
在经常指各个领域的新的改革,推动事物发生根本变革,引起事物从旧质变为新质的飞跃。<p
>

标红的部分没有加上链接,当然看我们的正则,就会知道因为包含‘<‘和‘>‘标签,所以匹配失败了。

修改我们的正则,只排出a标签即可,如下

static string pattern = @"\((?<author>(?!.*?<\s*a).*?)《(?<bookname>(?!.*?<\s*a).*?)》(?<other>.*?)\)";

这个正则(author和bookname分组)的意思是 任意字符(.*?)的开头,后边不跟(?!)着<a(中间可以有空格),最后边是任意字符(.*?)结尾

我是参考这里,了解(?!)的用法。

运行效果如下:

<p>[例]当夫广州之首难,武汉兴师,革命精神,震铄一世。(<a href=‘#‘></a>《<a href=‘
#‘>东方杂志</a>》1912年第9卷第1号)|欲去此不平等与压制,继政治革命而谋社会革命者,
社会主义是也。(<a href=‘#‘></a>《<a href=‘#‘>青年杂志</a>》1915年第1卷第1号)|俄
、德等国的劳工社会,首先看破他们的野心,不惜在大战的时候,起了社会革命,防遏这资本家
政府的战争。(<a href=‘#‘>李大钊</a>《<a href=‘#‘>庶民的<font color=‘red‘>胜利</f
ont></a>》1918年)|近年来文学革命的运动渐见功效,除了几个讲“纲常名教”的经学家。
(<a href=‘#‘>周作人</a>《<a href=‘#‘>思想革命</a>》1919年)</p><p>[按] “革命”本
指实施变革以应天命。“革命”现在经常指各个领域的新的改革,推动事物发生根本变革,引
起事物从旧质变为新质的飞跃。<p>

这里,我们就可以给特殊标签的内容添加上链接了。

小结

工作用到的东西,时间久了不用就会忘,及时记录一下。

正则表达式替换很好用,但是如果要针对每一组数据处理完(为空或者取到对应数据)再替换,则需要遍历每一次匹配结果再替换了。

正则表达式替换和不包含指定字符串

时间: 2024-08-07 04:54:34

正则表达式替换和不包含指定字符串的相关文章

PHP判断字符串中是否包含指定字符串,支持中文哦

RT,随手写的 1 /** 2 * 判断字符串中是否包含指定字符串 3 * @var source 源字符串 4 * @var target 要判断的是否包含的字符串 5 * @return bool 6 */ 7 function hasstring($source,$target){ 8 preg_match_all("/$target/sim", $source, $strResult, PREG_PATTERN_ORDER); 9 return !empty($strResul

Sql Server 删除表名包含指定字符串的表

删除包含指定字符串的表 create procedure sys_DeleteTableByTableName(@bianliang varchar(100))asbegindeclare @biao varchar(100),@sql varchar(1000)set @sql='%'[email protected]+'%'declare c cursor for select name from sysobjects where type='u' and name like @sqlset

列出当前目录所有包含指定字符串的文件

1.linux查找目录下的所有文件中是否含有某个字符串: find . -type f |xargs grep helloworld 2.列出当前目录所有包含指定字符串的文件: find . |xargs grep -ri "IBM" -l

php检测字符串中是否包含指定字符串

1.$str= 'abc'; $needle= 'a'; if( strpos($str, $needle) === false ){ } 2.strstr() 函数搜索一个字符串在另一个字符串中的第一次出现. 如果未找到所搜索的字符串,则返回 false $email = '[email protected]'; $domain = strstr($email, '@'); 3. stristr 如果没有找到该字符串,则返回 false.    它和strstr的使用方法完全一样.唯一的区别是

Js 利用正则 在字符串中提取数字、替换非数字字符为指定字符串

var s ="总金额4500元"; var num= s.replace(/[^0-9]/ig,""); alert(num);//4500 上述示例会把数字匹配到直接转成数字: var s ="总金额4500元,利润:28"; var num = s.replace(/[^0-9]/ig,""); alert(num);//450028   如果遇到字符夹带数字的情况:上述就会直接转成数字拼接起来的方式: 原文地址:htt

[转]notepad++正则表达式替换字符串详解

原文:http://blog.csdn.net/qinboecjtu/article/details/6035028 正则表达式是一个查询的字符串,它包含一般的字符和一些特殊的字符,特殊字符可以扩展查找字符串的能力,正则表达式在查找和替换字符串的作用不可忽视,它 能很好提高工作效率. EditPlus的查找,替换,文件中查找支持以下的正则表达式: 表达式 说明 /t 制表符. /n 新行. . 匹配任意字符. | 匹配表达式左边和右边的字符. 例如, "ab|bc" 匹配 "

EditPlus正则表达式替换字符串详解

网上搜集了些实例 正则表达式是一个查询的字符串,它包含一般的字符和一些特殊的字符,特殊字符可以扩展查找字符串的能力,正则表达式在查找和替换字符串的作用不可忽视,它能很好提高工作效率. EditPlus的查找,替换,文件中查找支持以下的正则表达式: Expression Description\t Tab character.\n New line.. Matches any character.| Either expression on its left and right side matc

javascript中通过replace函数搜索和替换指定字符串

javascript中我们可以通过replace函数替换部分字符串为指定字符串,本文展示了replace的详细用法,并且通过范例演示了如何进行部分替换.完整替换和不区分大小写替换. javascript中我们可以通过replace函数替换部分字符串为指定字符串.下面是replace函数的基本语法: str_var.replace("search_string", "replace_string") 下面看一个简单的范例: <script type="

notepad++正则表达式替换字符串详解

表达式 说明\t 制表符.\n 新行.. 匹配任意字符.| 匹配表达式左边和右边的字符. 例如, "ab|bc" 匹配 "ab" 或者 "bc".[] 匹配列表之中的任何单个字符. 例如, "[ab]" 匹配 "a" 或者 "b". "[0-9]" 匹配任意数字.[^] 匹配列表之外的任何单个字符. 例如, "[^ab]" 匹配 "a&q