用于简化 HQL 语法的正则表达式
我打算为我的视图/业务层提供将字符串中的 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
HQL 没有正则表达式,因为 HQL 不是正则语言。
要快速修复,您可以使用 非贪婪修饰符
?
对于每个.+
:结果:
我还想提一下,在例如
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.+
:Result:
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.
我不确定正则表达式是最好的工具。我宁愿尝试 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.
我不会尝试将 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.