Как я могу вытащить адрес электронной почты из строки key=value пар?

Реализация по умолчанию компилятора C# добавления обработчика событий звонит Delegate.Combine, в то время как удаление обработчика событий звонит Delegate.Remove:

Fire = (MyDelegate) Delegate.Remove(Fire, new MyDelegate(Program.OnFire));

реализация Платформы Delegate.Remove не смотрит эти MyDelegate сам объект, но в методе делегат обращается к (Program.OnFire). Таким образом совершенно безопасно создать новое MyDelegate объект при отмене подписки существующего обработчика событий. Из-за этого компилятор C# позволяет Вам использовать синтаксис стенографии (который генерирует точно тот же код негласно) при добавлении/удалении обработчиков событий: можно опустить new MyDelegate часть:

Fire += OnFire;
Fire -= OnFire;

, Когда последний делегат удален из обработчика событий, Delegate.Remove пустой указатель возвратов. Как Вы узнали, важно проверить событие по пустому указателю прежде, чем повысить его:

MyDelegate handler = Fire;
if (handler != null)
    handler("Hello 3");

Это присвоено временной локальной переменной для защиты от возможного состояния состязания с отказывающимися от подписки обработчиками событий на других потоках. (См. мое сообщение в блоге для получения дополнительной информации о потокобезопасности присвоения обработчика событий к локальной переменной.) Другой способ защитить от этой проблемы состоит в том, чтобы создать пустого делегата, который всегда подписывается; в то время как это использует немного больше памяти, обработчик событий никогда не может быть пустым (и код может быть более простым):

public static event MyDelegate Fire = delegate { };

5
задан Jon Seigel 28 March 2010 в 22:07
поделиться

6 ответов

Есть несколько способов сделать это. Вы можете разделить строку на пробел, а затем передать ее в TStringList. Затем вы можете использовать свойство Value [String] TStringList для получения значения заданного имени.

Для этого замените все пробелы запятыми:

newString := StringReplace(oldString, ' ', ',', [rfReplaceAll]);

Затем импортируйте результат в TStringList:

var
  MyStringList : TStringList;
begin
  MyStringList := TStringList.Create;
  try
    MyStringList.CommaText := StringReplace(oldString, ' ', ',', [rfReplaceAll]);
    Result := MyStringList.Values['email'];
  finally
    MyStringList.Free;
  end;
end;

Это даст вам значение электронной почты. Затем вам необходимо разделить строку по символу «@», что является относительно тривиальным упражнением. Конечно, это работает только в том случае, если пробелы действительно являются разделителем между полями.

В качестве альтернативы вы можете использовать регулярное выражение, но Delphi не поддерживает его изначально (вам понадобится библиотека регулярных выражений - см. здесь )

*** Smasher заметил (D2006 +) разделитель / текст с разделителями, который будет выглядеть примерно так:

MyStringList.Delimiter := ' ';
MyStringList.DelimitedText := oldString;
Result := MyStringList.Values['email'];
11
ответ дан 18 December 2019 в 10:46
поделиться

Следующий код работает, только если значения не содержат пробелов:

uses
  StrUtils, Classes;

....

function GetPropertyValue (const PropertyName : String; const InputString : String) : String;
var
  StringList : TStringList;
  Str : String;
begin
Result := '';
StringList := TStringList.Create;
try
  StringList.Delimiter := ' ';
  StringList.DelimitedText := InputString;
  for Str in StringList do
    if StartsText (PropertyName + '=', Str) then
      Result := RightStr (Str, Length (Str) - Length (PropertyName) - 1);    
finally
  FreeAndNil (StringList);
end;
end;
1
ответ дан 18 December 2019 в 10:46
поделиться

Еще одна идея, вы также можете использовать PosEx (StrUtils) с текстом StringList:

function ExtractMyString(SrcStr, FromStr, ToStr: string): string;
var
  posBeg, posEnd: integer;
begin
  Result := '';
  posBeg := Pos(FromStr, SrcStr) + Length(FromStr);
  posEnd := PosEx(ToStr, SrcStr, posBeg);

  if (posBeg > 0) and (posEnd > posBeg) then
    Result := Copy(SrcStr, posBeg, posEnd-posBeg);
end;

Использование:

ExtractMyString(StringList.Text, 'email=', ' lots=');

Конечно, это будет работать только в том случае, если исходная строка всегда форматируется одинаково , будет удобно для извлечения других данных по мере необходимости.

1
ответ дан 18 December 2019 в 10:46
поделиться

Моя идея:

  1. заменить пробелы на CRLF (они разделены пробелами)
  2. загрузить в TStringList
  3. использовать свойство значений с именем 'email'
2
ответ дан 18 December 2019 в 10:46
поделиться

предполагая, что строка содержится в переменной 's', а 'tmp' является другой строковой переменной,

i:= pos ('email=', s);
tmp:= '';
inc (i);
while s[i] <> ' ' do
 begin
  tmp:= tmp + s[i]; 
  inc (i);
 end;

'tmp' будет содержать адрес

1
ответ дан 18 December 2019 в 10:46
поделиться

Разделите строку на массив строк, используя '=' в качестве разделителя, тогда у вас будет массив в следующем порядке: 'Ключ', затем 'Значение', вы можете затем зациклить путем поиска ключа «email» просто добавьте 1 к индексу массива, чтобы получить значение. Но это могло произойти по-разному (например, кто-то вводит '=' как символ) или в поле значения есть пустые строки

0
ответ дан 18 December 2019 в 10:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: