case insensitive Pos

前端 未结 9 1515
一个人的身影
一个人的身影 2021-02-02 00:56

Is there any comparable function like Pos that is not case-sensitive in D2010 (unicode)?

I know I can use Pos(AnsiUpperCase(FindString), AnsiUpperCase(SourceString)) but

相关标签:
9条回答
  • 2021-02-02 01:20

    Here's one that I wrote and have been using for years:

    function XPos( const cSubStr, cString :string ) :integer;
    var
      nLen0, nLen1, nCnt, nCnt2 :integer;
      cFirst :Char;
    begin
      nLen0 := Length(cSubStr);
      nLen1 := Length(cString);
    
      if nLen0 > nLen1 then
        begin
          // the substr is longer than the cString
          result := 0;
        end
    
      else if nLen0 = 0 then
        begin
          // null substr not allowed
          result := 0;
        end
    
      else
    
        begin
    
          // the outer loop finds the first matching character....
          cFirst := UpCase( cSubStr[1] );
          result := 0;
    
          for nCnt := 1 to nLen1 - nLen0 + 1 do
            begin
    
              if UpCase( cString[nCnt] ) = cFirst then
                begin
                  // this might be the start of the substring...at least the first
                  // character matches....
                  result := nCnt;
    
                  for nCnt2 := 2 to nLen0 do
                    begin
    
                      if UpCase( cString[nCnt + nCnt2 - 1] ) <> UpCase( cSubStr[nCnt2] ) then
                        begin
                          // failed
                          result := 0;
                          break;
                        end;
    
                    end;
    
                end;
    
    
              if result > 0 then
                break;
            end;
    
    
        end;
    end;
    
    
    0 讨论(0)
  • 2021-02-02 01:27

    The Jedi Code Library has StrIPos and thousands of other useful functions to complement Delphi's RTL. When I still worked a lot in Delphi, JCL and its visual brother JVCL were among the first things I added to a freshly installed Delphi.

    0 讨论(0)
  • 2021-02-02 01:27

    On this occasion I couldn't find any approach that was even as good as, let alone better than Pos() + some form of string normalisation (upper/lowercase conversion).

    This is not entirely surprising as when benchmarked the Unicode string handling in Delphi 2009 I found that the Pos() RTL routine has improved significantly since Delphi 7, explained in part by the fact that aspects of the FastCode libraries have been incorporated into the RTL for some time now.

    The FastStrings library on the other hand has not - iirc - been significantly updated for a long time now. In tests I found that many FastStrings routines have in fact been overtaken by the equivalent RTL functions (with a couple of exceptions, explained by the unavoidable overhead incurred by the additional complications of Unicode).

    The "Char-Wise" processing of the solution presented by Steve is the best so far imho.

    Any approach that involves normalising the entire strings (both string and sub-string) risks introducing errors in any character-based position in the results due to the fact that with Unicode strings a case conversion may result in a change in the length of the string (some characters convert to more/fewer characters in a case conversion).

    These may be rare cases but Steve's routine avoids them and is only about 10% slower than the already quite fast Pos + Uppercase (your benchmarking results don't tally with mine on that score).

    0 讨论(0)
提交回复
热议问题