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

发布于 2024-09-19 04:08:42 字数 1332 浏览 1 评论 0原文

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

然而,数据层需要分析和操作这些查询(特别是在where子句中添加条件)。

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

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

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

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.Name 与“%X”不同)且 e.StatusID 不按 e.DateCreated desc 顺序排列(7、8、9)

感谢以下任何帮助:

  • 如何修复正则表达式?
  • 有 HQL 的正则表达式吗? (谷歌搜索找到了 HQL 语言的正则表达式功能)
  • 更好的想法仍然足够简单,可以在一天或更短的时间内实现?

I intended to provide my view/business layer with the possibility to send HQL queries in strings to my data layer.

However, the data layer needs to analyze and manipulate these queries (in particular, add a criterion in the where clause).

The supported forms of HQL queries are any combination of the following:

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

I think this kind of simplified HQL query should be regex-able, and this is the Regex I defined:

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);

Update: I've even tried with the non-greedy modifier:

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

However, when I try to match a string containing the where and the order by clause, the "order by" keyword is regarded as part of the where clause:

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);

gives

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

Any of the following help is appreciated:

  • How to fix the regexp?
  • Is there a regexp for HQL? (Googling leads to regexp-features of the HQL language)
  • Better idea which is still simple enough to implement in a day or less?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

滥情空心 2024-09-26 04:08:42

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

要快速修复,您可以使用 非贪婪修饰符 ? 对于每个 .+

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 执行此操作,则可以查看文章 使用 ANTLR:HQL 语法

There isn't a regular expression for HQL because HQL isn't a regular language.

To make a quick fix you could use the non-greedy modifier ? for each .+:

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);

Result:

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

I'd also like to mention that it is pointless to include the a word-boundary in for example order\b\s+\bby. There must always be a word boundary between r and a whitespace character so there is no need to specify it.

If you wish to do this with ANTLR then you could look at the article Working with ANTLR: HQL Grammar.

吖咩 2024-09-26 04:08:42

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

I'm not sure the regex are the best tool for that. I'd rather try ANTLR and define a small grammar to parse your HQL-lite queries.

兔小萌 2024-09-26 04:08:42

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

请参阅 何时不在 C# 中使用 Regex(或Java、C++ 等)

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

否则,某个地方一定有人编写了 HQL 查询的解析器,请查看使用 HQL 的任何开源项目的源代码。

I would not try to use Regex for anything as complex as HQL because HQL isn't a regular language.

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

As you can in control of both ends, I would consider representing your query as a tree of objects, that you then convert to/from xml or json. That way you will not have to write any string parsing code yourself.

Otherwise, someone somewhere must have written a parser for HQL queries, look at the source code for any open source projects that use HQL.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文