字符串处理【Delphi版】

一、几个字符串处理的基本函数

   a)子串定位——获取子串在原字串中的位置(不是数组下标,而是第几个) 

1 function pos('子串''原字符串'):integer

    说明:当有中文时,最好这样用:pos('子串',wideString('原字符串')),这样可以避免前一个汉字的后半部分和后一个汉字的前半部分 也恰好能构成一个汉字时出现问题。

 

  b)子串截取——拷贝出原字符串中的部分子串(Index不是数组下标,而是第几个)

1 function Copy(S; Index, Count: Integer):string

  
说明:其实该函数也可对字符数组进行拷贝操作,只不过“源数据”和“返回数据”都是字符数组

             function Copy(S; Index, Count: Integer):array

    附:另几个更有针对性的截取操作

           1)截取源字符串左端一定长度位数:StrUtils.pas
                 function LeftStr(Const Str:String;Size:word):string;
           2)截取源字符串中间一定长度位数:StrUtils.pas
                 function MidStr(Const Str:String;From,Size:word):string;
           3)截取源字符串右端一定长度位数:StrUtils.pas
                 function RightStr(Const Str:String;Size:word):string;

 

   c)字符串分割——利用分割符将原串分割成若干个子串

1 strList:=TStringList.create;
2 strList.delimiter:='|';
3 strList.delimitedText:='待|分|割|的|字|符|串';

    说明:  这样操作之后,分割得到的每条元素都分别存于strList中

 

   d)长度计算——计算字符串的长度

 function Length(S): Integer;

  

   e)长度设定——人为指定字符串的长度

 procedure SetLength(var S; NewLength: Integer);

    字符串显示时,会根据设置的长度值而不是后面的结束符#0,来决定显示的“字符长度”

 

   f)字符串填充

 var
  SourceString,ResultString:string;
 begin
  SourceString:='ABCD';
  //ResultString为8位,不足高位用‘0’填充
  ResultString:=StringOfChar('0',8-length(SourceString))+sourcestring;
  ShowMessage(ResultString);//最终结果为‘0000ABCD’
 end;

    说明:对位数不足的字符串,在高位置以特定的字符进行填充

   g)字符串中添加分隔符(自定义函数)

function DelimiterInsert(Const s: String; Const sCut: String): String; 
var
  i: Integer;
begin
  i:= 1 ;
  while i < length(s) do
  begin
    if i = 1 then
      Result := copy(s, i, 2)
    else
      Result := Result + sCut+ Copy(s, i, 2);
    i := i + 2;
  end;
end;

     测试:

var
  sourceStr,destinateStr:string;
begin
  sourceStr:='abcdefgh';
  destinateStr := DelimiterInsert(sourceStr, '-');//每两个字符之间加上“-”

  ShowMessage(destinateStr);
end;

    运行结果:

  

  h)单引号

     aa := 'aaa''' ;那么aa的结果就是aaa'
    实际上就是两个单引号表示一个单引号  bb:='bb''bb';bb的结果为 bb'bb

  i)ascii码转换成字符

var
  ss:string;
begin
  ss:=char(65)+char(66);
  ShowMessage(ss);
end;

    运行结果:

   

   j)字符替换

var
  ss:string;
begin
  ss:='aaabbbccc';
  ss:=StringReplace(ss, 'b', 'm', [rfReplaceAll]);
  ShowMessage(ss);
end;

    运行结果:

   

 

 

注: 更全面的字符串处理函数,可参考:

                                          a)http://ideasforjava.javaeye.com/blog/850360
                                          b)Delphi帮助文档,Help—>Delphi Help 下strUtils 

二、string,pchar,字符数组三者之间的相互转换  

a)String类型在内存中的分配

   

       说明:1)结束符#0其实只是为了兼容pchar类型,实际输出字符串时,是根据“字符串长度”中存储的数值,而不是结束符#0,代码如下:

var
SrcString:string;
begin
SrcString:='12345';//此时长度为5
ShowMessage('原始字符串为:'+SrcString);
SrcString:=SrcString+'AddStr'; //此时字符串为“12345AddStr”,长度也会自动修改为11
showmessage('追加之后的字符串:'+SrcString); //显示为:“12345AddStr”
SetLength(SrcString,3); //字符串长度人为设置为3,实际长度应该是11
ShowMessage('人为设置长度后字符串为:'+SrcString);//根据存储的长度值显 示,而非结束符#0,最终输出‘123
end;

 

                2)引用计数的作用是:当指向该堆空间的指针个数为零时,编译器自动释放堆内存,而不需

                                           要手动释放

               3)采用copy on write机制,以提高内存空间的利用率

      附:什么是copy on write机制?

            多个引用指向同一块内存地址。当其中的某个引用发生写操作时,重新拷贝一份到其他内存中,同时

       原引用计数减1。这样做是为了提高内存的利用率。

            缺陷:string类型作为参数时,尽管一开始“临时引用”和“原始引用”都指向堆中的同一块内存,

                      当在调用到的函数体内,对“临时引用”指向的内存块进行写操作时,实际上会把该内存块

                      的内容拷贝出来并结合具体的操作,生成调用者需要的字符串,存入新开辟的一块堆内存中,

                      此时“原始引用”指向的那块内存块的内容并没有发生改变,这也是为什么无法用string类型

                      作为输出参数传递函数返回值(但可以用作输入参数),而是使用PChar类型作为输出参数

                      传递函数返回值

                      被调用的以string类型作为“输出参数”的函数:          

procedure TForm1.StringTypeAsOutputParam(SourceStr:string);
begin
SourceStr:=SourceStr+'bbbbb';
showmessage('修改之后的字符串为:'+SourceStr);//显示为:aaaaabbbbbb
end;

                      调用该函数:

var
mySourceStr:string;
begin
mySourceStr:='aaaaa';
showmessage('原始字符串为:'+mySourceStr); //显示为:'aaaaa'
StringTypeAsOutputParam(mySourceStr); //将string类型作为输出参数传入
showmessage('调用函数之后的字符串为:'+mySourceStr);//依然显示为:'aaaaa'
end;

 

b)String与Pchar

    两者兼容,可直接进行“类型强转”

1 var
2 myString:string;
3 myPchar:PChar;
4  begin
5 myString:='ABCDEFG';
6 ShowMessage('转换之前的字符串为:'+myString); //此时字符串为 ‘ABCDEF’
7 myPchar:=PChar(myString);
8 mystring:=string(myPchar);
9 ShowMessage('连续转换后的字符串为:'+myString); //此时字符串仍为 ‘ABCDEF’
10  end;

c)字符数组与Pchar

   1)字符数组下标从0开始

 

   2)字符数组下标从1开始

var
  myArrayChar:array[1..10] of Char;
  myPchar:PChar;
begin
  myPchar:=PChar('ABCDEF');
  StrCopy(@myArrayChar,myPchar); // 也可使用 StrPCopy(@myArrayChar,'ABCDEF');
  ShowMessage(myArrayChar[1]); //输出值为 ‘A’ 注:此时若以myArrayChar[0]来访问会无法通过编译
  myArrayChar[1]:='1';
  myPchar:=PChar(@myArrayChar);
  ShowMessage(string(myPchar)); //整个字符串为‘1BCDEF’
end;

  

d)string与字符数组 :需要借助pchar类型过渡

1var
2 myString:string;
3 myArrayChar:array[1..10] of Char;
4begin
5 myString:='ABCDEF';
6 StrCopy(@myArraychar,PChar(myString));//也可以使用 StrPCopy(@myArraychar,myString);
7 myArrayChar[1]:='1';
8 myString:=string(PChar(@myArrayChar));
9 ShowMessage(myString); //转换后的值为‘1BCDEF’
10end;

注: StrCopy与StrPCopy的区别

     参数类型:    StrCopy(pchar类型,pchar类型);

                      StrPCopy(pchar类型,string类型);

e)推荐用法:

    1)字符串拷贝时

            StrPCopy(pchar类型,string类型);

    2)需要将字符串作为“输出参数”时

            使用PChar类型

    3)定义字符数组时

            charArray:array[0..n] of char ;//下标尽可能从0开始,而不是从1开始

f)string与widestring 

   string: Ansi字符集
   widestring: Unicode字符集

原文地址:https://www.cnblogs.com/edisonfeng/p/1985530.html