[技术问答] 字符串中的查找与替换

[复制链接]
 楼主| mickit 发表于 2024-5-31 10:00 | 显示全部楼层 |阅读模式
常用字处理软件或者编辑器都提供字符串的查找和替换功能,本文描述如何借助C语言的字符串处理函数来实现字符串的查找和替换功能。

先说查找,字符串的查找主要使用strstr函数,其原型为:char * strstr(char * str1, char * str2),函数的功能是在str1中查找str2,如果str2是str1的子串,则返回str2在str1中第一次出现的位置,否则返回空指针。
str2可能在str1中出现多次,如果希望把所有的str2都找出来,调用一次strstr是不够的,必须多次使用strstr函数,而且要不断更新str1。用一个简单例子来说明基本思路,在str1中查找the这个单词, str1=“I will give you the book the day aftertomorrow.”, str2=“the”。第一次调用strstr函数:p = strstr(str1, str2),找到了第一个the,返回值是这个the的地址,即指针p指向字母t。接下来需要在第一个the后面的字符串(也就是剩余字符串)中寻找其它的the,所以我们要将str1更换为剩余字符串,然后再调用strstr函数,也就是说在剩余字符串中找第一个the。借助p来实现这个更换,把p移到the后面,用p作为剩余字符串的首地址,即 p=p+3; p= strstr(p, str2)。这次就找到了第二个the,p指向了第二个the中的字母t。循环这个过程,直到p为空指针,就可以找到所有的str2。

下面说替换,意思就是用另一个字符串str3来替换str1中所有的str2。替换过程和查找的过程可以合并在一起,在上面循环查找的过程中,每找到一个str2,就把它替换为str3,替换后移动指针p。替换的情况分好几种:一种是str2和str3的长度相同,一种是str3比str2长,一种是str3比str2短。第一种情况比较简单,直接使用strncpy函数就可以,后面两种情况,都需要把str1中的元素进行移动。比如,在上面的例子中,str2=“the”,假设str3 =“this”,str3比str2长,为了有足够的空间,每找到一个the,从the后面的字符开始到结尾的‘\0’都要往后移动1个字节,也就是给this腾出4个字节的地方来(the的3个字节加移出来的1个字节)。假设str3 =“ok”,str3比str2短,为了填补空缺,每找到一个the,从the后面的字符开始到结尾的‘\0’都要往前移动1个字节,也就是给ok留出两个字节的地方就够了。移动过后,使用strncpy函数把str3拷贝到str2所在的地方。下面的程序中,str_replace就是用来实现替换功能的。

  1. #include "string.h"
  2. #include "stdio.h"

  3. void str_replace(char * cp, int n, char * str)
  4. {
  5.         int lenofstr;
  6.         int i;
  7.         char * tmp;
  8.         lenofstr = strlen(str);
  9.         //str3比str2短,往前移动
  10.         if(lenofstr < n)  
  11.         {
  12.                 tmp = cp+n;
  13.                 while(*tmp)
  14.                 {
  15.                         *(tmp-(n-lenofstr)) = *tmp; //n-lenofstr是移动的距离
  16.                         tmp++;
  17.                 }
  18.                 *(tmp-(n-lenofstr)) = *tmp; //move '\0'       
  19.         }
  20.         else
  21.                 //str3比str2长,往后移动
  22.                 if(lenofstr > n)
  23.                 {
  24.                         tmp = cp;
  25.                         while(*tmp) tmp++;
  26.                         while(tmp>=cp+n)
  27.                         {
  28.                                 *(tmp+(lenofstr-n)) = *tmp;
  29.                                 tmp--;
  30.                         }   
  31.                 }
  32.         strncpy(cp,str,lenofstr);
  33. }

  34. int main()
  35. {

  36.            char str1[1024];
  37.         char str2[100],str3[100];         
  38.            int i,len,count=0;
  39.            char c;
  40.            char *p;         
  41.           
  42.            printf("\n请输入要查找的字符串和用于替换的字符串(中间用空格隔开): ");
  43.            scanf("%s",str2);
  44.         scanf("%s",str3);
  45.         //read string from news.txt
  46.         freopen("news.txt","r",stdin);
  47.         i=0;
  48.         c = getchar();
  49.         while(c!=EOF)
  50.         {
  51.                 str1[i] = c;
  52.                 i++;
  53.                 c = getchar();
  54.         }
  55.         str1[i]        = '\0';
  56.        
  57.         //开始查找字符串str2
  58.            p = strstr(str1,str2);
  59.            while(p)
  60.         {
  61.                 count++;
  62.                 //每找到一个str2,就用str3来替换
  63.                 str_replace(p,strlen(str2),str3);
  64.                 p = p+strlen(str3);
  65.                 p = strstr(p,str2);
  66.         }          
  67.            printf("\ncount = %d\n",count);
  68.         printf("Result = %s\n",str1);        
  69. }


可怜的小弗朗士 发表于 2024-6-1 17:17 | 显示全部楼层
这两个很常用
deliahouse887 发表于 2024-6-4 10:06 | 显示全部楼层
在查找和替换字符串时,需要注意大小写敏感性。如果需要忽略大小写进行查找和替换,可以先将字符串转换为统一的大小写格式
qiufengsd 发表于 2024-6-4 11:10 | 显示全部楼层
注意空格和特殊字符的处理。在某些情况下,空格和特殊字符(如标点符号、制表符等)也需要被考虑在内。
wengh2016 发表于 2024-6-4 12:54 | 显示全部楼层
正则表达式是一种强大的文本处理工具,但也需要谨慎使用,以避免出现意外的匹配结果或性能问题。
robincotton 发表于 2024-6-4 16:54 | 显示全部楼层
优化算法或使用更高效的库函数可能很有必要。
loutin 发表于 2024-6-5 12:49 | 显示全部楼层
替换操作可能会改变字符串的长度              
wwppd 发表于 2024-6-8 19:45 | 显示全部楼层
在字符串中,有些字符如正则表达式的元字符(如 *.+?[]{}() 等),在查找时需要进行转义。否则,这些字符会被解释为特殊的含义,而不是单纯的字符匹配。
maqianqu 发表于 2024-6-9 12:17 | 显示全部楼层
在替换操作中,需要注意替换模式,比如是否需要替换全部匹配项,还是仅替换首次出现的匹配项。在一些编程语言中,可以指定替换第一个匹配的选项或者全局替换选项。
olivem55arlowe 发表于 2024-6-9 17:10 | 显示全部楼层
在进行字符串替换时,需要注意全局替换和局部替换的区别。全局替换会替换字符串中所有匹配的子串,而局部替换只会替换第一个匹配的子串。
ingramward 发表于 2024-6-9 20:56 | 显示全部楼层
大多数查找操作默认是区分大小写的,这意味着大写和小写字母会被视为不同的字符。如果需要忽略大小写,可以使用如strcasestr这样的函数,或在比较之前转换字符串至统一的大小写形式。
yeates333 发表于 2024-6-10 16:07 | 显示全部楼层
在对重要数据进行查找和替换之前,最好先备份原始数据。这样,在发生错误或不满意的更改时,可以恢复到原始状态。
uiint 发表于 2024-6-10 19:38 | 显示全部楼层
选择合适的库函数或编写自己的查找与替换函数。例如,在C语言中,可以使用strstr()函数来查找子字符串,使用strncpy()或自定义函数来进行替换。
cemaj 发表于 2024-6-11 15:52 | 显示全部楼层
在进行循环内的查找替换时,特别是当替换后的字符串仍可能匹配查找条件时,要小心避免无限循环。
claretttt 发表于 2024-6-11 19:02 | 显示全部楼层
在进行字符串查找时,需要明确是否区分大小写。有些查找方法默认区分大小写,而有些则不区分。
earlmax 发表于 2024-6-12 10:27 | 显示全部楼层
应当对查找和替换函数进行充分的测试,特别是边界条件,如空字符串、只包含空白字符的字符串或非常长的字符串等。这有助于发现和修复潜在的错误。
bestwell 发表于 2024-6-12 13:34 | 显示全部楼层
对于查找操作,需要处理未找到匹配项的情况,避免程序异常。替换操作也要考虑替换失败的边缘情况。
juliestephen 发表于 2024-6-12 17:39 | 显示全部楼层
在处理大量字符串时,需要考虑查找和替换操作的性能。避免使用低效的算法或方法,以减少计算时间和内存消耗。
eefas 发表于 2024-6-12 21:22 | 显示全部楼层
在进行替换操作时,要特别注意不要产生重叠的索引。例如,如果原始字符串是"abc",同时存在两个替换操作分别作用于索引0和1,源字分别是"ab"和"bc",这将导致问题,因为这两个操作有重叠部分。为避免这种情况,需要保证替换操作之间没有重叠的部分。
51xlf 发表于 2024-6-13 19:43 | 显示全部楼层
所处理的字符串采用的字符编码(如ASCII,UTF-8等),因为不同的编码方式会影响到字符的表示和比较。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

89

主题

1533

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部