正则表达式用于简化的HQL语法

时间:2010-09-09 08:52:18

标签: c# regex hql

我打算为我的视图/业务层提供将字符串中的HQL查询发送到我的数据层的可能性。

但是,数据层需要分析和操作这些查询(特别是在where子句中添加一个标准)。

支持的HQL查询形式是以下任意组合:

from ...
where ...
order by ...

我认为这种简化的HQL查询应该是regex-able,这是我定义的正则表达式:

public const string HqlRegex = @"^(\bfrom\b\s*(?<FromPart>.+)\s*)?"
    + @"(\bwhere\b\s*(?<WherePart>.+)\s*)?"
    + @"(\border\b\s+\bby\b\s*(?<OrderByPart>.+))?$";

Regex re = new Regex(Novartis.MapAdmeBs.NHibernateDAO.DAOFactory.HqlRegex,
    RegexOptions.Singleline);

更新:我甚至尝试过使用非贪婪的修饰符:

public const string HqlRegex = @"^(\bfrom\b\s*(?<FromPart>.+?)\s*)?"
    + @"(\bwhere\b\s*(?<WherePart>.+?)\s*)?"
    + @"(\border\b\s+\bby\b\s*(?<OrderByPart>.+?))?$";

但是,当我尝试匹配包含where order by子句的字符串时,“order by”关键字被视为where子句的一部分:

Match m = re.Match("where (e.Name not like '%X') and e.StatusID not in (7, 8, 9)"
                 + " order by e.DateCreated desc");
Console.WriteLine(m.Groups["WherePart"].Value);

给出

  

(e。名称不像'%X')和e.StatusID不在(7,8,9)的顺序中由e.DateCreated desc

赞赏以下任何帮助:

  • 如何修复正则表达式?
  • HQL是否有正则表达式? (谷歌搜索导致HQL语言的regexp功能)
  • 更好的想法仍然很简单,可以在一天或更短时间内实施?

3 个答案:

答案 0 :(得分:2)

HQL没有正则表达式,因为HQL不是常规语言。

要快速解决问题,您可以为每个?使用non-greedy modifier .+

string hqlRegex = @"^(\bfrom\b\s*(?<FromPart>.+?)\s*)?"
    + @"(\bwhere\b\s*(?<WherePart>.+?)\s*)?"
    + @"(\border\b\s+\bby\b\s*(?<OrderByPart>.+?))?$";

Regex re = new Regex(hqlRegex);
Match m = re.Match("where (e.Name not like '%X') and e.StatusID not in (7, 8, 9)"
         + " order by e.DateCreated desc");
string wherePart = m.Groups["WherePart"].Value;
Console.WriteLine(wherePart);

结果:

(e.Name not like '%X') and e.StatusID not in (7, 8, 9)

我还想提一下,例如order\b\s+\bby中包含一个单词边界是没有意义的。在r和空白字符之间必须始终有一个单词边界,因此不需要指定它。

如果您希望使用ANTLR执行此操作,那么您可以查看文章Working with ANTLR: HQL Grammar

答案 1 :(得分:1)

我不确定正则表达式是最好的工具。我宁愿尝试ANTLR并定义一个小语法来解析你的HQL-lite查询。

答案 2 :(得分:1)

我不会尝试将Regex用于像HQL这样复杂的任何东西,因为HQL不是常规语言。

请参阅When not to use Regex in C# (or Java, C++, etc.)

正如您可以控制两端,我会考虑将您的查询表示为对象树,然后将其转换为xml或json。这样你就不必自己编写任何字符串解析代码了。

否则,有人必须为HQL查询编写解析器,查看使用HQL的任何开源项目的源代码。