我需要正则表达式帮助创建一个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)
欢呼和谢谢.
在我的原始代码中,我正在寻找分隔符并将所有内容作为我的下一个匹配项,但是当在引号内查找某些内容时,这个概念并没有延续下去。@Stephan 否定搜索的建议最终使我找到了可行的方法。我之前从未提到过的另一个复杂之处是 HyperStr 可以使用任何内容作为引用字符。默认为双引号,但您可以通过函数调用更改它。
在我的解决方案中,我已将 QuoteChar 显式硬编码为双引号,这适合我自己的目的,但将 QuoteChar 设为全局并将其设置在另一个函数中是微不足道的。我还成功地用单引号(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 进行测试。也许其他人知道?