如何在正则表达式中跳过引用的文本(或如何在Unicode文本中使用HyperStr ParseWord?)

mar*_*rcp 5 regex delphi

我需要正则表达式帮助创建一个delphi函数来替换Rad Studio XE2中的HyperString ParseWord函数.HyperString是一个非常有用的字符串库,从未跳转到Unicode.我得到它主要工作,但它根本不尊重引用分隔符.我需要它与下面描述的功能完全匹配:

function ParseWord(const Source,Table:String; var Index:Integer):String;

使用单字符分隔符表的顺序,从左到右的令牌解析.引用字符串中的分隔符将被忽略.表中不允许使用引号分隔符.

索引是由函数更新为指向下一个单词的指针(初始化为第一个单词的'1').要检索下一个单词,只需使用先前返回的索引值再次调用该函数.

注意:如果Length(Resultant)= 0,则没有其他单词可用. 引用字符串中的分隔符将被忽略.(我的重点)

这是我到目前为止:

function ParseWord( const Source, Table: String; var Index: Integer):string;
var
  RE : TRegEx;
  match : TMatch;
  Table2,
  chars : string;
begin
  if index = length(Source) then
  begin
    result:= '';
    exit;
  end;

  // escape the special characters and wrap in a Group
  Table2 :='['+TRegEx.Escape(Table, false)+']';
  RE := TRegEx.create(Table2);
  match := RE.Match(Source,Index);
  if match.success then
  begin
    result := copy( Source, Index, match.Index - Index);
    Index := match.Index+match.Length;
  end
  else
  begin
    result := copy(Source, Index, length(Source)-Index+1);
    Index := length(Source);
  end;
end;

  while ( Length(result)= 0) and (Index<length(Source)) do
  begin
    Inc(Index);
    result := ParseWord(Source,Table, Index);
  end;
Run Code Online (Sandbox Code Playgroud)

欢呼和谢谢.

mar*_*rcp 0

在我的原始代码中,我正在寻找分隔符并将所有内容作为我的下一个匹配项,但是当在引号内查找某些内容时,这个概念并没有延续下去。@Stephan 否定搜索的建议最终使我找到了可行的方法。我之前从未提到过的另一个复杂之处是 HyperStr 可以使用任何内容作为引用字符。默认为双引号,但您可以通过函数调用更改它。

在我的解决方案中,我已将 QuoteChar 显式硬编码为双引号,这适合我自己的目的,但将 Q​​uoteChar 设为全局并将其设置在另一个函数中是微不足道的。我还成功地用单引号(ascii 39)测试了它,这在 Delphi 中是棘手的。

function ParseWord( const Source, Table: String; var Index: Integer):string;
var
  RE : TRegEx;
  match : TMatch;
  Table2: string;
  Source2 : string;
  QuoteChar : string;
begin
  if index = length(Source) then
  begin
    result:= '';
    exit;
  end;

  // escape the special characters and wrap in a Group
  QuoteChar := #39;
  Table2 :='[^'+TRegEx.Escape(Table, false)+QuoteChar+']*|'+QuoteChar+'.*?'+QuoteChar ;
  Source2 := copy(Source, Index, length(Source)-index+1);
  match := TRegEx.Match(Source2,Table2);
  if match.success then
  begin
    result := copy( Source2, match.index, match.length);
    Index := Index + match.Index + match.Length-1;
  end
  else
  begin
    result := copy(Source, Index, length(Source)-Index+1);
    Index := length(Source);
  end;
  while ( Length(result)= 0) and (Index<length(Source)) do
  begin
    Inc(Index);
    result := ParseWord(Source,Table, Index);
  end;

end;
Run Code Online (Sandbox Code Playgroud)

此解决方案不会从带引号的字符串中删除引号字符,但我无法从我自己的现有代码中判断是否应该删除引号字符,并且我无法使用 Hyperstr 进行测试。也许其他人知道?