Object Pascal 正则表达式提取任意关键字之间的字符串

Object Pascal Regular Expression Extract String between arbitrary keywords

使用 TRegExpr(或任何类似的东西)提取 SQL select 语句的 WHERE 子句的正确代码是什么,如果存在,它会在“group by”处停止, 或者在 'order by' 如果存在,或者在语句末尾如果 'group by' 和 'order by' 都不存在?

输入字符串:

select p.PRODUCT_TYPE_ID, p.PRODUCT_TYPE_NAME
from PRODUCT_TYPE
where p.PRODUCT_TYPE_NAME containing :PRODUCT_TYPE_NAME
group by whatever
order by p.PRODUCT_TYPE_NAME

尝试了正则表达式:

where[\s]+(.+)(\s+group\s+by\s+|\s+order\s+by\s+|)

此正则表达式适用于我尝试过的在线解析器,但不适用于此 Pascal 代码:

Program HelloWorld(output);
uses
  regexpr, classes;


var
  re: tregexpr;
  s: string;
begin
  
  s := 'select p.PRODUCT_TYPE_ID, p.PRODUCT_TYPE_NAME '+
    'from PRODUCT_TYPE '+
    'where p.PRODUCT_TYPE_NAME containing :PRODUCT_TYPE_NAME '+
    'order by whatever '+
    'group by whatever';
    
  re := tregexpr.create;
  re.ModifierStr := '-i';
  re.expression := 'where[\s]+(.+)(\s+group\s+by\s+|\s+order\s+by\s+|)';
  re.inputstring := s;
  
  re.Exec(s);
  
  writeln('match[1]');
  writeln(re.match[1]);
  
  re.free;
  
end.

我尝试使用 ?: 将第二组转换为非捕获,但无济于事。

where[\s]+(.+)(\s+group\s+by\s+|\s+order\s+by\s+|)

文档说支持非捕获组,但后来的 FAQ 与它相矛盾,或者我漏掉了什么。

我期待匹配 [1] 到 return p.PRODUTCT_TYPE_NAME 包含:PRODUCT_TYPE_NAME

我知道 #@#$% 正则表达式,但我确实安装了 trunk,所以我可以测试。

输出为:

匹配[1] p.PRODUCT_TYPE_NAME 包含:PRODUCT_TYPE_NAME 按任何组按任何

排序

我会试试这个:

re.expression := 'where\s+(.+?)(\s+group\s+by\s+|\s+order\s+by\s+|\s+$)';

我在第一组中用+?替换了+。这是“惰性”捕获模式。

我在第二组中用|\s+$)替换了|)$ 表示“字符串的结尾”。

我不能确定它是否适用于您可能想要使用它的所有情况,但它适用于您提供的示例。

顺便说一句,不需要这两行:

re.modifierstr := '-i';
re.inputstring := s;