【问题标题】:Parse Url querystring with delphi 5使用 delphi 5 解析 URL 查询字符串
【发布时间】:2019-10-31 14:21:51
【问题描述】:

我有这个字符串:

Called=%2B12608883475&ToState=IN&CallerCountry=US&Direction=inbound&CallerState=IN&ToZip=&CallSid=CAb7faaa30058c2347a595630f2475113a&To=%2B12608883475&CallerZip=

我想通过& 解析它以获取所有参数,然后按字母顺序对参数进行排序,区分大小写。

所有这些都必须在 Delphi 5 中完成:

Function TwilioSignatureValidate(twilioSignature: string; QueryString: string ; Url: string): boolean;
begin
  parameters := QueryString;
  List := TStringList.Create;
end;

这是我要复制的 C# 版本:

string input = "Called=%2B12608883475&ToState=IN&CallerCountry=US&Direction=inbound&CallerState=IN&ToZip=&CallSid=CAb7faaa30058c2347a595630f2475113a&To=%2B12608883475&CallerZip=";

Dictionary<string,string> keyValuePairs = input.Split('&')
    .Select(value => value.Split('='))
    .ToDictionary(pair => pair[0], pair => pair[1]);

string studentId = keyValuePairs["StudentId"];

使用 List.Sort;

我得到了我的 Delphi 列表按字母顺序排序,但它不是使用 Unix 风格的区分大小写的排序顺序: //德尔福排序 https://ffbc1360.ngrok.io 帐户SidACc6d06b4cb61ccbfa61bf461957a5a626 api版本2010-04-01 拨打+12608883475 被称为城市 称为国家美国 调用状态IN 叫Zip 来电者+12602060582 来电城 来电国家美国 来电者状态IN 来电邮编 呼叫SidCAb7faaa30058c2347a595630f2475113a CallStatusringing 方向入站 来自+12602060582 来自城市 FromCountryUS 来自StateIN FromZip 至+12608883475 城市 去往美国 ToStateIN 压缩包

//正确的c#排序 https://ffbc1360.ngrok.io 帐户SidACc6d06b4cb61ccbfa61bf461957a5a626 api版本2010-04-01 呼叫SidCAb7faaa30058c2347a595630f2475113a CallStatusringing 拨打+12608883475 被称为城市 称为国家美国 调用状态IN 叫Zip 来电者+12602060582 来电城 来电国 美国来电者 状态输入 来电邮编 方向入站 来自+12602060582 来自城市 FromCountryUS 来自StateIN FromZip 至+12608883475 城市 去往美国 ToStateIN 压缩包

【问题讨论】:

  • 到目前为止你尝试过什么?你被困在哪里了?
  • 您的具体问题是什么?
  • 如何将我的查询字符串排序到一个列表中,我是 Delphi 的新手。
  • 发布几乎完全被注释掉的代码就像根本不发布代码一样没用。您发布的代码显然不是您使用 Delphi 5 所做的,因为 Delphi 5 不支持泛型或 TStringBuilder。

标签: parsing delphi query-string


【解决方案1】:

TStringList 在 Delphi 6 及更高版本中具有 DelimiterDelimitedTextCaseSensitive 属性。将Delimiter 设置为'&amp;',然后将查询字符串分配给DelimitedText,然后您可以使用Values[] 属性按名称提取值(因为生成的分隔字符串已经是name=value 格式)。无需排序:

Function TwilioSignatureValidate(twilioSignature: string; QueryString: string ; Url: string): boolean;
var
  List: TStringList;
begin
  List := TStringList.Create;
  try
    List.Delimiter := '&';
    List.DelimitedText := QueryString;
    List.CaseSensitive := True;

    // use List.Values['param name'] as needed, eg:
    // List.Values['Called']
    // List.Values['ToState']
    // List.Values['CallerCountry']
    // List.Values['Direction']
    // List.Values['CallerState']
    // List.Values['ToZip']
    // List.Values['CallSid']
    // List.Values['To']
    // List.Values['CallerZip']
  finally
    List.Free;
  end;
end;

但是,在 Delphi 5 中,这些属性都不存在,因此您必须手动完成所有操作:

Function TwilioSignatureValidate(twilioSignature: string; QueryString: string ; Url: string): boolean;
var
  List: TStringList;

  // the following are tweaked from TStrings in later Delphi versions...

  procedure MySetDelimitedText(const Value: string);
  var
    P, P1: PChar;
    S: string;
  begin
    List.BeginUpdate;
    try
      List.Clear;
      P := PChar(Value);
      while P^ <> #0 do
      begin
        if P^ = '"' then
          S := AnsiExtractQuotedStr(P, '"')
        else
        begin
          P1 := P;
          while (P^ <> #0) and (P^ <> '&') do
            P := CharNext(P);
          SetString(S, P1, P - P1);
        end;
        List.Add(S);
        if P^ = '&' then
        begin
          P := CharNext(P);
          if P^ = #0 then
            List.Add('');
        end;
      end;
    finally
      List.EndUpdate;
    end;
  end;

  function MyIndexOfName(const Name: string): Integer;
  var
    P: Integer;
    S: string;
  begin
    for Result := 0 to List.Count - 1 do
    begin
      S := List.Strings[Result];
      P := AnsiPos('=', S);
      if (P <> 0) and (AnsiCompareStr(Copy(S, 1, P - 1), Name) = 0) then Exit;
    end;
    Result := -1;
  end;

  function MyGetValue(const Name: string): string;
  var
    I: Integer;
  begin
    I := MyIndexOfName(Name);
    if I >= 0 then
      Result := Copy(List.Strings[I], Length(Name) + 2, MaxInt) else
      Result := '';
  end;

begin
  List := TStringList.Create;
  try
    MySetDelimitedText(QueryString);

    // use MyGetValue('param name') as needed, eg:
    // MyGetValue('Called')
    // MyGetValue('ToState')
    // MyGetValue('CallerCountry')
    // MyGetValue('Direction')
    // MyGetValue('CallerState')
    // MyGetValue('ToZip')
    // MyGetValue('CallSid')
    // MyGetValue('To')
    // MyGetValue('CallerZip')
  finally
    List.Free;
  end;
end;

【讨论】:

  • 我在尝试使用 Tstring 属性时遇到这样的错误。 [错误] TwilioSignatureValidateFunctions.pas(49):未声明的标识符:'CaseSensitive'
  • @brucecopper 对不起,我的错,我忘了 DelimiterDelimitedTextCaseSensitive 是在 Delphi 6 中添加的。我已经更新了我的答案
  • 效果很好,您知道按字母顺序对列表进行排序的方法吗?
  • @brucecopper TStringList 在 Delphi 5 中具有 Sorted 属性,以及 Sort()CustomSort() 方法。但是,SortedSort() 不考虑 name=value 对仅对 name 进行排序,它们对整个字符串进行排序,因此如果您只想对 name 进行排序,则必须使用CustomSort() 为此。
猜你喜欢
  • 2010-11-25
  • 1970-01-01
  • 2012-04-24
  • 1970-01-01
  • 2019-05-03
  • 2011-02-27
  • 1970-01-01
  • 2021-10-26
  • 1970-01-01
相关资源
最近更新 更多