разбор строки по разделителю

evgen29
Дата: 13.06.2019 16:20:42
Здравствуйте! Есть Certificate.SubjectName, который содержит строку, разделенную запятыми.
SN = Фамилия, G = Имя, T = Должность, Неструктурированное имя = Тестовый, STREET = "Тестовый адрес, улица, дом, квартира", CN = ТЕСТ, OU = Подразделение, O = ИП Тест, L = Истра, S = Московская, C = RU, E = test@test.ru, ИНН = 123456789012, ОГРН = 1234567890123


можно это конечно загнать в StringList и разбить по DelimitedText, но у меня delphi 7 такое не может(код на нем, переносить нельзя), потому как не учитывает двойные кавычки и поле STREET понимает после разбиения как 4 поля( в этом примере). Вопрос - как получить значение каждого поля, чтобы учесть экранирование двойными кавычками?
Dimitry Sibiryakov
Дата: 13.06.2019 16:26:50

evgen29
как получить значение каждого поля, чтобы учесть экранирование двойными кавычками?

Простенький парсер на основе конечного автомата пишется за пару часов с нуля.

Posted via ActualForum NNTP Server 1.5

Мимопроходящий
Дата: 13.06.2019 16:31:44

13.06.2019 16:20, evgen29 пишет:
> можно это конечно загнать в StringList и разбить по DelimitedText, но у меня delphi 7 такое не может

QuoteChar поставь нужный

Posted via ActualForum NNTP Server 1.5

antox
Дата: 13.06.2019 16:31:57
Раньше вроде как-то так делали - тексте листа через стринг реплэйс меняли ЗПТ на #13#10, если я не ошибаюсь
DarkMaster
Дата: 13.06.2019 17:01:18
Заменить имена полей и = на CRLF, сложить в стринг лист. У каждой строки в списке - убрать последнию запятую и убрать пустые строки.
evgen29
Дата: 13.06.2019 23:57:35
сделал через регулярные выражения.
Пример с одной кнопкой и полем ввода
в поле ввода текст такой же как в начале
может кому пригодится.
ps: регулярку конечно надо будет поменять в дальнейшем, учесть нюансы типа О'Брайан и прочее.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, RegExpr;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function GetCurrentCertInfo(str: string): WideString;
const
  expr = '(([a-zA-Z0-9а-яА-ЯёЁ_]+\s*)+=\s*([''"].*[''"]\s*|[a-zA-Z0-9а-яА-ЯёЁ_@\.\s]*),?)+';
var
  HeaderColumns: TStringList;
  i: integer;
  strreplace,match: string;
  r: TRegExpr;
begin
  strreplace:='';
  r := TRegExpr.Create;
  try // ensure memory clean-up
    r.Expression := expr;
    if r.Exec(str) then
      repeat
        match:=r.Match[0];
        if match[length(match)]=',' then match:=copy(match,0,length(trim(match))-1);
        strreplace := strreplace+match+chr(13)+chr(10);
      until not r.ExecNext;
  finally r.Free;
  end;
  result:=strreplace;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  SL: TStringList;
  str: string;
begin
    try
      SL := TStringList.Create;
      SL.Text := GetCurrentCertInfo(Edit1.Text);
      str := SL.Values['SN'];
      str := SL.Values['E'];
      str := SL.Values['T'];
    finally
      SL.Free;
    end;
end;

end.


исходник модуля прикреплен и доступен по ссылке на проект:
https://regex.sorokin.engineer/ru/latest/index.html
Ghost Writer
Дата: 14.06.2019 00:08:45
evgen29
Вопрос - как получить значение каждого поля, чтобы учесть экранирование двойными кавычками?
получать SubjectName из сертификата сразу в нормальном виде, с разбиением по строкам и без лишних кавычек:
CertNameToStr + CERT_X500_NAME_STR or CERT_NAME_STR_CRLF_FLAG or CERT_NAME_STR_NO_QUOTING_FLAG
evgen29
Дата: 14.06.2019 10:04:23
Ghost Writer,
а можно если не трудно строку кода, как метод объекта capicom или cadescom, а не набор констант? Просто к чему этот набор констант привязан не совсем ясно.
delphinotes
Дата: 14.06.2019 10:28:22
Дарю. В Delphi 7 правда в таком виде не скомпилируется, но поменять record на object, либо вытащить методы из recorda, думаю труда не составит?
Василий 2
Дата: 14.06.2019 10:58:55
А на кавычках внутри кавычек эта регулярка сломается ?