Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
scala使用正则表达式来提取sql语句中的fields子句_Sql_Regex - Fatal编程技术网

scala使用正则表达式来提取sql语句中的fields子句

scala使用正则表达式来提取sql语句中的fields子句,sql,regex,Sql,Regex,我想开发一个简单的函数来替换sql语句中的fields子句 像这样的 replaceFields("select * from x", "f1") // should return "select f1 from x" replaceFields("select top 10 * FROM x", "f1") // should return "select top 10 f1 FROM x" replaceFields("select top 10 f3, f4 FROM

我想开发一个简单的函数来替换sql语句中的fields子句

像这样的

replaceFields("select  * from x", "f1")
// should return "select f1 from x"

replaceFields("select top 10 *   FROM x", "f1")
// should return "select top 10 f1   FROM x"

replaceFields("select top 10 f3, f4    FROM x", "f1, f2")
// should return "select top 10 f1, f2    FROM x"
我知道这应该很简单,但我尝试了一些正则表达式,但似乎找不到

"select * from".replaceFirst("""select (\w+) from""", "count(*)")
// returns "select * from"

"select * from".replaceFirst("""select(\b(.*))\bfrom""", "count(*)")
// returns "count(*)"

但它不起作用…

您正在正确地更换

select(\b(.*))\bfrom
如果只想替换
选择
from
之间的部分,则不应将这些部分包含在要替换的字符串中。试一试

(?<=select\b)(.*?) from
编辑:

似乎要替换表中的列列表

假设每个列名都位于select语句后面的关键字列表(如
TOP
)之后,我创建了这个正则表达式,其中包含相关参数

(([^\s]+,\s+)*([^\s]+)\s+)from
它基于这样一个原则:列名(您要替换的列名)要么是来自的
前面的标记(请允许我用这个词),要么是用逗号将其与其他标记分开

然后以这种方式处理该案件

token token, token FROM
      ^this is the starting point of substitution

token FROM
^this is the starting point

用你想要的替换第一组,你就没事了。测试它

多亏了gabber的帮助,以及(并非如此)对正则表达式的一点点挣扎,我找到了这个解决方案:

def replaceFields(sql: String, fields: String): String = {
  val parseSql = """(?imx)                #insensitive case, multiline, whitespaces and comments
    (^ select \s+ #(?:top \s+ \d+ \s+)?)  #m1: select clause and optional clauses
      (?:top \s+ \d+ \s+)?                #  top x clause (ignored match)
      (?:(?:distinct|all) \s+)?           #  distinct | all clause (ignored match)
    )
    (.+?)                                 #m2: the field clause I'm looking for, non greedy to leave spaces to match3
    (\s+ from \s+ .* $)                   #m3: the rest of the sql sentence, greedy spaces
  """.r
  val replace = "$1%s$3".format(fields)   // replace match2 with new fields
  parseSql.replaceFirstIn(sql, replace)
}
其中:

scala> replaceFields("select * from x", "count(*)")
res1: String = select count(*) from x

scala> replaceFields("select top 24 f1, f2 from x", "f3, f4, f5")
res2: String = select top 24 f3, f4, f5 from x

scala> replaceFields("select  f1  from x", " f2,  f3 ")
res3: String = select   f2,  f3   from x

scala> replaceFields("select top 23 distinct f1, f2 from x", "f3, f4, f5")
res0: String = select top 23 distinct f3, f4, f5 from x

“没用”。。。发生了什么事?我在每行后面添加了表达式返回的内容作为注释。。。将为clarityAh编辑它,对吧对不起,我看到了第一个列表,但忽略了第二个列表。这里是它不起作用的原因:第一个没有找到
*
,因为
\w
将只匹配
[a-zA-Z0-9]
。第二个不匹配,但完全匹配表示整个字符串,因此替换整个字符串。我不知道这在您的环境中是如何工作的,但是您需要替换第一个捕获组。另外,您的第二个模式将包括捕获中的空格。您的预期结果
从x中选择前10个计数(*)无效。这只是一个示例,可能有任何字段列表,我将对其进行编辑以获得清晰的答案非常有用,问题是在fields子句中可能有一些奇怪的内容,如“select Upper”表1中的(f1)、f2*2等”是的,我认为这不可能适用于所有情况。我认为最好的解决方案是设置一组关键字,可以在select语句之后找到,并将它们放在正则表达式中的
列表中,就像您对
top
所做的那样,但使用其他代码段,如
DISTINCT
添加了DISTINCT和all支持:)你找到答案后,最多只能给你+1个奖励!小心,如果您编写
(\s+from\s+
),则在from前面需要两个空格,后面需要三个空格
\s+
表示1+个空格,然后在
\s+
中的
之间添加一个空格。同样的事情在(?imx)开始时,“x”告诉scala忽略这些空白,所以这与写入(\s+来自\s+.*$)是一样的,我认为我的版本更具可读性……事实上,我只是不知道这个特性:)
scala> replaceFields("select * from x", "count(*)")
res1: String = select count(*) from x

scala> replaceFields("select top 24 f1, f2 from x", "f3, f4, f5")
res2: String = select top 24 f3, f4, f5 from x

scala> replaceFields("select  f1  from x", " f2,  f3 ")
res3: String = select   f2,  f3   from x

scala> replaceFields("select top 23 distinct f1, f2 from x", "f3, f4, f5")
res0: String = select top 23 distinct f3, f4, f5 from x