【问题标题】:How to select column names and tables of an SQL using regex?如何使用正则表达式选择 SQL 的列名和表?
【发布时间】:2014-10-07 13:44:31
【问题描述】:

我有一个如下所示的 SQL 字符串:

SELECT
    USER."ID", USER."NAME", USER."BIRTH",USER."GENDER",
    PACKAGE."type"
    PACKAGE."code"
FROM
    "DBNAME"."USER" USER,
    "DBNAME2"."PACKAGE" PACKAGE
WHERE
    USER."PACKAGE_ID" = PACKAGE."ID"
ORDER BY
    USER."NAME";

我应该如何在 C# 中编写正则表达式来提取 SELECT 和 FROM 关键字之间的所有列名,然后是 FROM 子句中的表名?

预期的输出应该找到这些,以便我可以将它们放入List 以循环:

列列表:

USER."ID"
USER."NAME"
USER."BIRTH"
USER."GENDER"
PACKAGE."type"
PACKAGE."code"

表格列表:

"DBNAME"."USER" USER
"DBNAME2"."PACKAGE" PACKAGE

【问题讨论】:

  • 你能展示一个期望输出的例子吗?
  • 使用词法分析器比正则表达式更容易解析 SQL。
  • 正则表达式是此类事情中使用最多(误用)的工具。你需要一个解析器。 @hjpotter92 的词法分析器可能还不够。签出这个 impl here at codeproject。这可能更适合您当前的需求,但可以很好地适应未来的需求。查询变得复杂,您可能需要的不仅仅是列名和表名。
  • @inquisitive 不幸的是,codeproject 的实现目前不支持 select 子句。 :(

标签: c# sql .net regex


【解决方案1】:

使用这个正则表达式会得到列名和表名:

  (?is)SELECT(.*?)(?<!\w*")FROM(?!\w*?")(.*?)(?=WHERE|ORDER|$)
  • 组[1] : 栏
  • 组[2]:表名

代码示例:

string sql=@"SELECT
    USER.""ID"", USER.""NAME"", USER.""BIRTH"",USER.""GENDER"",
    PACKAGE.""type""
    PACKAGE.""code""
FROM
    ""DBNAME"".""USER"" USER,
    ""DBNAME2"".""PACKAGE"" PACKAGE
WHERE
    USER.""PACKAGE_ID"" = PACKAGE.""ID""
ORDER BY
    USER.""NAME"";";

    var reg=new Regex(@"(?is)SELECT(.*?)(?<!\w*"")FROM(?!\w*?"")(.*?)(?=WHERE|ORDER|$)");
    var colunms=reg.Match(sql).Groups[1].Value.Split(new char[]{','},StringSplitOptions.RemoveEmptyEntries);
    var tables=reg.Match(sql).Groups[2].Value.Split(new char[]{','},StringSplitOptions.RemoveEmptyEntries);

【讨论】:

  • 谢谢!这个效果很好。除了我意识到列名中带有“FROM”字样的 SQL 会导致提取错误。说Select USER."FROM_COUNTRY"...,这将导致正则表达式中断。
  • 感谢您的更新。但它似乎仍然不起作用。我有一个类似于 select USER."TRAVEL_FROM_COUNTRY"... 的查询,由于 FROM 关键字,正则表达式将在 TRAVEL_ 之后立即停止。
  • @Carven 用我的正则表达式测试USER."TRAVEL_FROM_COUNTRY",效果很好。你可以列出你的测试 sql,然后我可以调试我的正则表达式代码。
  • 哦.. 我意识到发生了什么。在我拥有的一些 SQL 文件中,它们可能没有引号。所以,它们看起来像 USER.TRAVEL_FROM_COUNTRYUSER.FROM_COUNTRY。这将导致问题。有引号的可以,但没有引号的就不行。我该如何解决这个问题?
  • @Carven 提问时,您应该列出所有规则。这是最后一次更新:(?is)SELECT(.*?)(?&lt;!\w*["_])FROM(?!\w*?["_])(.*?)(?=WHERE|ORDER|$)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多