【问题标题】:Regex for filter过滤器的正则表达式
【发布时间】:2019-02-26 07:13:26
【问题描述】:

我有以下 .NET 正则表达式无法正常工作

  1. “val”组中有一个空格
  2. 'val' 组没有被单引号括起来

我正在使用正则表达式解决方案(不是解析器)来修改此模式以匹配上述两个问题。有更多正则表达式经验的人可以改进它吗?

(?\w+|`.+`|\[.+\])\s*(?[=]|LIKE)\s*(?'?) (?(?:[\S-[']]|(?:''))+)(?:\k\B)?(?:\s*(?( ?:AND)|(?:OR))\s*)?

REGEX STORM .Net Tester
该模式使用字符序列减法 - regex101 是否支持这一点?

捕获组: 如果字段包含空格或非字母数字,则字段可以选择用大括号 (`) 或方括号 ([]) 括起来。

值可以用单引号 (') 括起来。使用两个单引号转义单引号。使用方括号“[*]”和“[%]”转义通配符“*”和“%”。用方括号“[[]”和“[]]”转义方括号'['和']'

布尔运算符可以是 OR 或 AND

比较运算符可以是 =、 或 LIKE

模式是Microsoft Expression Filter 的简化,只处理上述子集。

应该工作的示例如下。
每个示例都在单独的行上。正则表达式可以在每一行上匹配多次。 例如:

"a LIKE 'b[*]' OR [b] LIKE 'c''s' AND d = f OR e = 'd'" 将匹配:

  1. “一个喜欢'b [*]'或”。此匹配的组:field="a"、operator=LIKE、val="b[*]"、boolean=OR。
  2. “[b] LIKE 'c''s' AND”。组:field="b"、operator=LIKE、val="c's"、boolean=AND。
  3. “d = f 或”。组:field="d"、operator="="、val="f"、boolean=OR。
  4. “e = 'd'”。组:field="e"、operator="="、val="d"、boolean=。但正则表达式与此文本不匹配。

a LIKE 'b[*]' OR [b] LIKE 'c''s' AND d = f OR e = 'd'
[a b] = 'd'
`e f g` > 'f'
g h = ' '
我 = '3'
[全名] = ''
名字喜欢“你好”
[名字] = 'g'
`年龄` > 6
`全名` = ''

【问题讨论】:

  • 请提供正则表达式必须适用的输入以及应该是什么输出
  • @HadiRj - 我认为整行应该匹配。尽管有一些不应该匹配的例子会很有帮助。 fwiw - 看起来 OP 想要使用正则表达式解析类似 sql 的语言。这永远不会是 100% 万无一失的。正则表达式不适合。
  • Regexbuddy 无法制作正则表达式的正面或反面。你能提供一个regex101 的样本吗?
  • 你的正则表达式也有Unrecognized grouping construct 错误。
  • @HadiRj,当我粘贴它时,该模式很好,但被 stackoverflow 破坏为错误的 html 标签。现已修复。

标签: .net regex


【解决方案1】:

从这里使用 .net 版本可以为您节省大量时间和麻烦?

SQL parsers for .net

我必须承认,我并不是从那些解析器的经验中说出来的,而是我从人们在使用正则表达式(包括年轻时的我自己)而不是解析器时遇到的 HTML/CSS 解析的类似问题中说的。

如果您采用解析器方法,它的可读性更高、更不容易出错、更易于调试或维护并且花费的总时间更少。

例如:

TGSqlParser sqlparser = new TGSqlParser(EDbVendor.dbvmysql);
        sqlparser.sqltext = "ALTER TABLE `world`.`t1` ALTER `c1` SET DEFAULT 'abc';";
        Assert.IsTrue(sqlparser.parse() == 0);

        TAlterTableStatement alterTableStatement = (TAlterTableStatement)sqlparser.sqlstatements.get(0);
        TAlterTableOption alterTableOption = alterTableStatement.AlterTableOptionList.getAlterTableOption(0);
        Assert.IsTrue(alterTableOption.OptionType == EAlterTableOptionType.AlterColumn);
        Assert.IsTrue(alterTableOption.DefaultExpr.ToString().Equals("'abc'", StringComparison.CurrentCultureIgnoreCase));

展示如何从 alter table 语句中成功提取 DEFAULT 的值:

"ALTER TABLE `world`.`t1` ALTER `c1` SET DEFAULT 'abc';";

我相信你可以对你的语句做类似的事情,只需传递你正在解析的任何字符串,而不是硬编码的文本。

很抱歉,这不是一个完整的(在拼盘上,复制粘贴)类型的答案,如果我认为它会很好地展示,我会把它放在评论中。希望通过这种方式,当您看到它的简单性时,您会改变主意。

我与作者没有任何关系,如果您发现更适合您的东西,我也不建议您使用此方法,我所说的只是使用此方法并展示它的实际演示。

【讨论】:

  • 我明白了。我可能想要失望。虽然我不需要/不想要完整的 SQL 解析。我想知道比我更了解正则表达式的人是否可以提供一种在不使用引号时也可以匹配 val 捕获组的模式;当使用引号并且 val 中有空格时也匹配。纯粹来自正则表达式解决方案,而不是解析器。
  • 很公平,我提高了您的问题以使其获得更多答案,但将其留作参考。有人可能会偶然发现这一点,我想让他看看有不同的选择。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-19
  • 2016-09-02
  • 2012-12-10
  • 2018-01-11
  • 1970-01-01
相关资源
最近更新 更多