如何在Emacs正则表达式中说“不是括号”?

时间:2018-03-07 14:56:21

标签: regex emacs elisp regex-negation

我想查找没有dbo.[dbo].前缀的所有行(在SQL脚本中)(通常看起来应该完全限定名称)。

例如,在以下文件中:

ALTER TABLE [dbo].[mo_scenario_em]
DROP CONSTRAINT [mo_scenario_em_scenario_id]
ALTER TABLE [team_assoc]                         -- <<< missing prefix
DROP CONSTRAINT [team_assoc_org_id]
ALTER TABLE dbo.asset_trans
DROP CONSTRAINT [DF__asset_tra__mod_f__5E90642B]
ALTER TABLE eq                                   -- <<< missing prefix
DROP CONSTRAINT [DF__eq__source_recor__2498CCC0]

我希望我的命令显示第3行和第7行。

无法正常工作采取此行动:

(defun show-missing-prefix ()
  "Show lines where there is no `dbo.' or `[dbo.]' prefix."
  (interactive)
  (occur (concat "ALTER TABLE [^d][^b][^o]"
                 "\\|" "ALTER TABLE \\[[^d][^b][^o]\\]"
                 "\\|" "CREATE FUNCTION [^d][^b][^o]"
                 )))

它不起作用,因为我看不到如何匹配ALTER TABLE行,但没有dbo.[dbo].

问题是我不知道如何在正则表达式中写“不是括号” - [^\\[][^\\]]不能使用AFAICS。

当然,它必须推广到其他SQL关键字,例如:

  • alter procedure
  • drop function
  • drop table
  • 插入
  • 更新

并且不区分大小写,但是一旦骨架完成工作,这应该没问题。

这可能以一种非常简单的方式实现吗? (或者它是否已经以某种方式存在?)

2 个答案:

答案 0 :(得分:2)

正如Drew,Triplee和jmg所说:

不是括号,您可以撤销订单:[^][]

不区分大小写的show-missing-prefix,由问题作者在下面的评论中发布,但遗失了$

(defun show-missing-prefix ()
  (interactive)
  (occur "\\(alter\\|drop\\|insert\\) *\\(table\\) *\\(\\[?[^\\. ]+\\]?\\)$"))

解决问题的另一个建议是,你可以从这样的事情开始:

query-replace-regexp

Regexp Match String:

\(alter\|drop\|insert\) *\(table\) *\(\[?[^. ]+\]?\)$

要字符串:

\1 \2 [dbo].\3)

使用转义()来定义替换字符串中引用的数字组:在这种情况下,\1是操作(提供3),\2是操作数(仅当前),\3是命名对象,它指定一系列不包含.(空格)的一个或多个字符。

在您的示例中,在删除缺少前缀注释后,此匹配的第3行和第7行添加了前缀。

Emacs附带re-builder,可让您在构建正则表达式时获得实时反馈,但您必须确保使用正确的语法模式。 read,默认模式,用于在编程中使用RE;所以要在re-builder中看到上面的正则表达式,你必须切换到string语法模式,这是交互使用的RE。 (使用C-c TAB更改语法模式。)

https://emacs.stackexchange.com/questions/5568/why-do-regular-expressions-created-with-the-regex-builder-use-syntax-different-f

那里有很多其他的包看起来可以提供帮助。 https://www.emacswiki.org/emacs/RegularExpression

此外,如果您在找到成功后(交互式地)想要完全转义命令的lisp,请查看command-history

(query-replace-regexp "\\(alter\\|drop\\|insert\\) *\\(table\\) *\\(\\[?[^\\. ]+\\]?\\)$" "\\1 \\2 [dbo].\\3" nil)

答案 1 :(得分:1)

在Emacs正则表达式中,以下字符串匹配任何不是左括号的字符:[^[]。至少在Emacs 25.3.1中。