字符串替换

题目:将某一字符串中的某段子串替换成新的字串,要求是原址(在源串上替换)替换,源串自己保证长度以便容纳新的字串。

例:

将 abcdefcdef 中的 c替换成gg,替换后的字符串:abggdefggef  ;

或将cde替换成a,替换后的字符串:abafaf。

代码:

/************************************************************************/
/*
	函数功能:用新子串替换源字符串中的子串(原址替换)
		说明:新串比旧串长时,需保证源buf足够容纳替换后的字符串
*/
/************************************************************************/
bool STR_Replace(char *szBuf,uint uiBufLen,char *oldStr,char *newStr)
{
	uint uiOldLen = 0;
	uint uiNewLen = 0;
	uint uiDstIndex = 0;
	uint uiLen = 0;
	char *pcLast = NULL;
	char *pcCurCursor = NULL;

	if ((NULL == szBuf) || (NULL == oldStr) || (NULL == newStr) || (uiBufLen<=0))
	{
		printf("Invalid inputs.p1(%p),p2(%u),p3(%p),p4(%p).",szBuf,uiBufLen,oldStr,newStr);
		return false;
	}
	
	uiOldLen = strlen(oldStr);
	uiNewLen = strlen(newStr);
	/* 旧串不能为空,新串可以为空 */
	if (0 == uiOldLen)
	{
		printf("Old str(%s) should not be null !",oldStr);
		return false;
	}
	
	if (uiNewLen > uiOldLen)
	{	
		/* 新串比旧串长(扩展替换) */
		return STR_Expand_Replace(szBuf,uiBufLen,oldStr,newStr);
	}
	else
	{
		/* 新串比旧串短 */
		pcLast =szBuf;
		pcCurCursor = strstr(pcLast,oldStr);	//寻找旧子串第一次出现的位置
	
		while ((NULL != pcCurCursor) && (uiDstIndex < uiBufLen))
		{
			uiLen = (uint)(pcCurCursor - pcLast);
			memcpy(szBuf+uiDstIndex,pcLast,uiLen);	//拷贝uiLen个长

			memcpy(szBuf+uiDstIndex+uiLen,newStr,uiNewLen);//拷贝新串
			uiDstIndex += (uiLen+uiNewLen);			//下次拷贝的起点(上面已经拷贝了uiLen+uiNewLen长)
			
			pcLast = pcCurCursor + uiOldLen;	//搜索下一个子串的起点
			pcCurCursor = strstr(pcLast,oldStr);	//定位下一个待替换子串位置
		}
//		strcpy(szBuf+uiDstIndex , pcLast,uiBufLen - uiDstIndex); //拷贝最末尾一段
		memcpy(szBuf+uiDstIndex , pcLast,uiBufLen - uiDstIndex);
	}
	return true;
}
/************************************************************************/
/*
	函数功能:用新子串替换源字符串中的子串(原址替换 新字串比旧字串长)
*/
/************************************************************************/
bool STR_Expand_Replace(char *szBuf,uint uiBufLen,char *oldStr,char *newStr)
{
	uint uiSrcStrLen = 0;
	uint uiOldLen =0;
	uint uiNewLen =0;
	uint uiCnt =0;		//记录旧字串出现的次数
	uint uiPartLen = 0;
	char *pcCurCursor = NULL;
	uint auiIndex[SUBSTR_MAX_CNT] = {0}; //保存每次查找到的字串的位置

	if ((NULL == szBuf) || (NULL == oldStr) || (NULL == newStr) || (uiBufLen <=0))
	{
		printf("Invalid inputs.p1(%p),p2(%u),p3(%p),p4(%p).",szBuf,uiBufLen,oldStr,newStr);
		return false;
	}
	uiSrcStrLen = strlen(szBuf);
	uiOldLen = strlen(oldStr);
	uiNewLen = strlen(newStr);
	assert(uiNewLen > uiOldLen);

	pcCurCursor = strstr(szBuf,oldStr);	
	while((NULL != pcCurCursor) && (uiCnt < SUBSTR_MAX_CNT))
	{
		auiIndex[uiCnt++] = (uint)(pcCurCursor- szBuf);
		//查找下一个旧字串位置
		pcCurCursor = strstr(pcCurCursor + uiOldLen,oldStr);
	}
	if ((NULL != pcCurCursor) && (uiCnt >= SUBSTR_MAX_CNT))
	{
		printf("Old str occur too many times :(%u)\n",uiCnt);	//旧字串出现次数太多
		return false;
	}
	if (uiSrcStrLen + (uiNewLen-uiOldLen)*uiCnt > uiBufLen)
	{
		/* 源buf不足以容纳替换后的字符串 */
		printf("SrcBuf cannot accommodata Newstr !\n");
		return false;
	}
	
	auiIndex[uiCnt] = uiSrcStrLen;
	pcCurCursor = szBuf+uiSrcStrLen+(uiNewLen-uiOldLen)*uiCnt ; //定位到末尾
	*pcCurCursor = '\0';		//加上末尾标识
	for (int i = uiCnt;i>0;--i)
	{
		uiPartLen = (auiIndex[i]-auiIndex[i-1])-uiOldLen;  //找到源串末尾部分段长(不包括旧串)
		pcCurCursor -= uiPartLen;
		//移动源串末尾部分段(不包括旧串)
		memmove(pcCurCursor,szBuf+auiIndex[i-1]+uiOldLen,uiPartLen); 
		//定位新串插入的位置
		pcCurCursor -= uiNewLen;
		//插入新串
		memcpy(pcCurCursor,newStr,uiNewLen);
	}
	pcCurCursor -= auiIndex[0];	//最后的pcCurCursor
	
	return true;
}
/************************************************************************/
/*
	字符串替换测试函数
*/
/************************************************************************/
void test_str_replace_fun()
{
	char pSrcStr[200] = "abcdefgbcg";
	char pOldStr_1[4]="bc";
	char pOldStr_2[2]="g";
	char pNewStr_1[2]="z";	//把bc替换成z
	char pNewStr_2[4]="opq"; //把g替换成opq

	printf("The src str : \n");
	printf("%s",pSrcStr);

	if(STR_Replace(pSrcStr,200,pOldStr_1,pNewStr_1))
	{
		printf("\nThe first replace(%s--%s) : \n",pOldStr_1,pNewStr_1);
		printf("( %s )\n",pSrcStr);
		
		if (STR_Replace(pSrcStr,200,pOldStr_2,pNewStr_2)) //失败 再测
		{
			printf("\nThe Second replace(%s--%s) : \n",pOldStr_2,pNewStr_2);
			printf("( %s )\n",pSrcStr);
		}
	}

	return ;
}
简单说明:

    通过pcCurCursor定位,每次替换(移动)源字符串中的一段。当新子串比旧子串长时,源串自己保证自己的buf足够大,且旧子串在源串中出现的次数不宜过多(这也满足绝大部分应用)。不懂的可以自己按照while循环执行步骤动手画画。

测试结果:


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
<h3>回答1:</h3><br/>shell 字符串替换是指在 shell 脚本中,通过指定一个字符串,将该字符串中的某些部分替换成另一个字符串。这个功能在处理文本文件时非常常见,可以帮助我们快速地修改文件内容,提高工作效率。在 shell 中,我们可以使用 sed、awk、tr 等命令来实现字符串替换功能。其中,sed 命令是最常用的字符串替换工具,它可以通过正则表达式来匹配需要替换的字符串,并将其替换成指定的字符串。例如,我们可以使用 sed 命令将一个文件中的所有 hello 替换成 world: ``` sed 's/hello/world/g' file.txt ``` 这个命令会将 file.txt 文件中的所有 hello 替换成 world,并输出到屏幕上。除了 sed 命令,我们还可以使用 awk 命令来实现字符串替换功能。awk 命令可以通过指定分隔符来分割字符串,并对每个分割后的字符串进行处理。例如,我们可以使用 awk 命令将一个文件中的第二列替换成指定的字符串: ``` awk '{ $2 = "world"; print }' file.txt ``` 这个命令会将 file.txt 文件中的第二列替换成 world,并输出到屏幕上。总之,shell 字符串替换是一项非常实用的功能,可以帮助我们快速地处理文本文件,提高工作效率。 <h3>回答2:</h3><br/>Shell 字符串替换是一种非常方便的操作,可以快速地替换字符串中的某个部分,使得字符串的内容得到调整或改变。Shell 字符串替换有内置的命令和函数,可以用来完成不同的替换需求。下面我们将重点介绍 Shell 字符串替换的几种方式: 一、基本替换 基本替换是 Shell 字符串替换的最基础形式。它通过使用 shell 中的“/”符号来实现。例如,我们要将字符串“hello world”中的“world”替换为“china”,那么可以使用下面的命令: ``` echo "hello world" | sed 's/world/china/g' ``` 其中,sed 是一个内置的字符串替换命令,它后面的 s 即表示 substitute,也就是替换的意思。第二个“/”符号后面是要替换的部分,第三个“/”符号后面是用来替换的部分。g 表示全局替换,即要将字符串中所有符合条件的部分都替换掉。 二、变量替换 在 Shell 中,我们可以使用变量来存储字符串。如果要对字符串进行替换,也可以采用变量替换的方式,即通过变量名来引用字符串,再对其进行替换。例如,我们定义一个字符串变量 str,并将其赋值为“hello world”: ``` str="hello world" ``` 然后,我们可以使用下面的命令将其中的“world”替换为“china”: ``` echo ${str/world/china} ``` 这里的 ${} 是变量替换的语法标记,其中 /world/china 即表示要将字符串中的“world”替换为“china”。需要注意的是,这种方式只会替换字符串中的第一个匹配项。 三、正则表达式替换 正则表达式是一类强大的字符串处理工具,很多字符串编辑操作都可以通过正则表达式实现。在 Shell 中,我们也可以使用正则表达式进行字符串替换。例如,我们要将字符串“hello 1 world 2”中的所有数字替换为空格,可以使用如下命令: ``` echo "hello 1 world 2" | sed 's/[0-9]/ /g' ``` 这里的 [0-9] 表示一个数字,即用来匹配字符串中的数字部分。与基本替换类似,我们使用 sed 命令来执行替换操作,其中 s 后面的正则表达式 [0-9] 表示要替换的内容,后面的 / / 表示用空格来替换匹配到的内容。 综上所述,Shell 字符串替换提供了多种方式来处理不同的替换需求。熟练掌握这些技巧,可以让我们更加高效地处理字符串相关的任务。 <h3>回答3:</h3><br/>Shell 字符串替换是指在字符串中查找特定字符串并将其替换为另一个字符串的过程。Shell 中有多种字符串替换命令和技巧,包括 `sed`、`awk`、`tr`、`cut`、`grep` 等。 其中最常用的是 `sed` 命令。`sed` 命令允许使用正则表达式进行搜索和替换,语法为 `sed 's/要替换的字符串/替换成的字符串/g' 文件名`。其中 `s` 表示替换操作,`g` 表示全局替换(即所有匹配的字符串都替换),还可以加上 `i` 表示忽略大小写。 例如,可以用 `sed 's/world/Hello/g' test.txt` 命令将 test.txt 文件中所有的 `world` 替换为 `Hello`。 除了 `sed` 命令,还有其他一些常见的字符串替换技巧: - 使用 `tr` 命令将一组字符转换为另一组字符,语法为 `tr '要替换的字符' '替换成的字符'`。例如,`echo "hello" | tr 'l' 'n'` 可以将 `hello` 替换为 `hennn`。 - 使用 `cut` 命令提取字符串的一部分,例如 `cut -c 1-3 test.txt` 可以提取 test.txt 文件中每行的前三个字符。 - 使用 `grep` 命令查找包含特定字符串的行,例如 `grep "hello" test.txt` 可以查找 test.txt 文件中包含 `hello` 的行。 总之,在 Shell 中进行字符串替换有多种方法和技巧,可以根据具体情况选择适合的方法。需要注意的是,在进行字符串替换时,应谨慎操作,避免误操作导致数据丢失或损坏。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

那个少年

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值