遇到了一个比较棘手的问题,向高手们请教给定一个模版字符串,其中可能含有'%1','%2'...'%6'的一个或几个,且'%1','%2'...'%6'出现的顺序不定
再给定另一个与这个模版相匹配的字符串
现在想要从匹配模版的这个字符串提取出对应'%1','%2'...'%6'的字串放在6个相应的变量里,这个应该怎么做?不知道我有没有说清楚,给个例子:
给定模版字符串:“%1 - %3 - %2”,相应的变量是var1,var3,var2
给定与之匹配的字符串:“str1 - str3 - str2”现在想要的功能是
取出'str1',赋给变量var1
取出'str3',赋给变量var3
取出'str2',赋给变量var2有劳各位高手了~分不够可以再加

解决方案 »

  1.   

    从大到小进行StringReplace
    tmpString:=StringReplace(tmpstr,'%10',var10,[rfReplaceAll]);
    tmpString:=StringReplace(tmpstr,'%9',var9,[rfReplaceAll]);
    tmpString:=StringReplace(tmpstr,'%8',var8,[rfReplaceAll]);
    tmpString:=StringReplace(tmpstr,'%7',var7,[rfReplaceAll]);
    ...
    tmpString:=StringReplace(tmpstr,'%1',var1,[rfReplaceAll]);
      

  2.   

    找到一种解决办法,但是执行效率很低,有没有更高效的?function getStr(pattern, patternStr, source: String): String;
    var
      tmpPos, i: Integer;
      prefix, suffix: String;
      startPos, endPos: Integer;
    begin
      Result := '';
      for i := 0 to 5 do
        if pattern <> ('%'+IntToStr(i)) then
          patternStr := ReplaceStr(patternStr, '%'+IntToStr(i), '|');
          
      tmpPos := pos(pattern, patternStr);
      if tmpPos > 0 then
      begin
        prefix := copy(patternStr, 0, tmpPos-1);
        suffix := copy(patternStr, tmpPos+2, 1);    while pos('|', prefix) > 0 do
        begin
          prefix := copy(prefix, pos('|', prefix)+1, Length(prefix));
        end;    if prefix <> '' then
          startPos := pos(prefix, source)+Length(prefix)
        else
          startPos := 0;
        if suffix <> '' then
          endPos := pos(suffix, source)-1
        else
          endPos := Length(source);
        Result := copy(source, startPos, endPos);
      end;
    end;patternStr := '%1 - %3 - %2';
    tmpString := 'str1 - str3 - str2';var1 := getStr('%1',patternStr,tmpString );
    var2 := getStr('%2',patternStr,tmpString );
    var3 := getStr('%3',patternStr,tmpString );
    var4 := getStr('%4',patternStr,tmpString );
    var5 := getStr('%5',patternStr,tmpString );
    var6 := getStr('%6',patternStr,tmpString );
      

  3.   

    555555, 在公司加班, 好痛苦. 无聊之下随手写了一段代码, 能解决你的问题. 由于我手头没delphi, 下面代码也许有语法错误. 如果你看懂了就不会来跟我说不能运行之类的话了.代码应该是比较优化的. 我觉得已经没必要进一步优化了. 再要优化其中的字符串搜索代码就要自己用汇编来写了.如果楼下哪位打算用Copy和pos来写相同功能的话那就要做好效率至少下降30%的思想准备.procedure FillVars(const Pattern, InputStr: string);
    const
        // var1~var6是你需要填数据的变量名
      VarRefs: array [0..5] of pointer = (@var1, @var2, @var3, @var4, @var5, @var6); 
    var
      VarPoses: array [0..5] of Integer;  // 记录模板与变量对应关系, VarPoses[i] = VarRefs中的下标
      PattSeps: array [0..6] of string;   // 记录InputString中的每两个目标字串中间的分隔符(从模板中获取)
      n, v: Integer;
      p, p1: PChar;
    begin
      p := Pattern;   // 不确定delphi是不是会重新copy一份临时字符串并让p指向复制出来的临时字符串, 
                      // 保险的话用 p := Pointer(Pattern)强制转换一下(注意一定要转成Pointer而不是PChar), 
                      // 这样编译器就不会生成字符串引用记数相关的代码也不会自动复制一份了
      n := 0;  {从Pattern字符串中获取VarPoses和PattSeps的内容}
      repeat
        p1 := StrScan(p, '%');  // 如果自己写个循环判断每个字符的话效率要比Delphi的StrScan高,
                                // 因为StrScan内部其实是两次循环, 第一次找出字串尾,
                                // 第二次才是真正的查找    {设置PattSeps[n]}
        if p1 = nil then      
          PattSeps[n] := p
        else begin
          SetString(PattSeps[n], p, Integer(p1)-Integer(p));      {并计算当前对应的是'%?'并填入VarPoses[n]}      {下面这个循环相当于StrToInt, 为了能只扫描一遍字符串就获得所有信息才有了这么奇怪的一个StrToInt}
          v := 0;
          p := p1;
          Inc(p);
          while p^ in ['0'..'9'] do
          begin
            v := v * 10 + Byte(p^)-Byte('0');
            Inc(p);
          end;
          VarPoses[n] := v;
        end;
        Inc(n);
      until p1 = nil;  {根据PattSeps分割InputStr获取一个目标字符串, 并根据VarPoses中指示的位置将此字符串填入VarRefs对应的变量中}  n := Pos(PattSeps[0], InputStr);  // 找到第一个分隔符
      p := @InputStr[n+Length(PattSeps[0])+1]; // 定位到InputStr中的开始位置  n := 0;
      repeat
        {获取PattSeps[n]和PattSeps[n+1]所包起来的字符串}
        p1 := StrPos(p, PChar(PattSeps[n+1])); //找到子串尾部
        if p1 <> nil then
        begin
          SetString(PString(VarRefs[VarPoses[n]])^, p, Integer(p1)-Integer(p)); // 将子串填入变量
          p := Pointer(Integer(p1)+length(PattSeps[n+1])); // 定位到下一个开始位置
        end;
        Inc(n);
      until p1 = nil;end;