Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.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
Regex 是否可以使用正则表达式与条件匹配?_Regex_Vim - Fatal编程技术网

Regex 是否可以使用正则表达式与条件匹配?

Regex 是否可以使用正则表达式与条件匹配?,regex,vim,Regex,Vim,我将此问题发布在上,有人建议我将此问题发布在stackoverflow上 我真的很喜欢vim,今天我遇到了一个有趣的问题,我认为它可以通过regexp完成,但我不能形成一个合适的 我有一个很大的sql文件。它合并了许多不同的查询。文件包含以下内容: select * from hr.employees, oe.orders, oe.order_items select * from hr.employess, oe.orders, hr.job_history select * from oe.

我将此问题发布在上,有人建议我将此问题发布在stackoverflow上

我真的很喜欢vim,今天我遇到了一个有趣的问题,我认为它可以通过regexp完成,但我不能形成一个合适的

我有一个很大的sql文件。它合并了许多不同的查询。文件包含以下内容:

select * from hr.employees, oe.orders, oe.order_items
select * from hr.employess, oe.orders, hr.job_history
select * from oe.customers, oe.orders, hr.employees
select * from hr.employees, hr.departments, hr.locations

如何仅选择该行,该行上只有一个与
hr.
匹配的行?。例如上面的第一行和第三行。

要检查行是否只包含一次出现的
hr。
请使用regex模式

^(?=.*\bhr\)(?!.*\bhr\..*\bhr\).
带有
m
修饰符。我建议使用
grep-P
实用程序


当然,可以匹配这些行。此模式匹配:

^\%(\%(hr\.\)\@!.\)*hr\.\%(\%(hr\.\)\@!.\)*$
有些人喜欢使用非常神奇的开关
\v
来减少反斜杠转义量。然后,相同的模式就变了

\v^%(%(hr\.)@!.)*hr\.%(%(hr\.)@!.)*$
更多信息请访问

  • :h:global
  • :h/\v
  • :h/\%(
  • :h/\@!

像这样的问题,我总是发现将其拆分为regex的多个用途更容易。如果我要用grep筛选,我会这样做:

grep "hr\." foo.sql
这给了我所有带有“hr”的行,甚至是带有两个的行

现在,我再次通过grep传输该输出,并要求它忽略出现两次的
hr.
行:

grep "hr\." foo.sql | grep -v "hr\..*hr\."

我知道你说的是vim,但我正在展示一些可能有用而且可能更清楚的替代方案。

为此,你需要将负向后看与负向前看断言相结合;即当前匹配模式不能在同一行中前后匹配。在vim中,这些模式的原子是
\@and
\@!

因此,查找单个X的模式如下:

/\%(X.*\)\@<!X\%(.*X\)\@!/

非常棒的图形。看起来几乎像EBNF latex软件包。事实上,您需要使用与PCRE兼容的regexp引擎,因为您的regexp语法不能与Vim一起使用(但可以这样重写)@ΩmegaΔ:我已经阅读了您的完整答案,以及明确提到Vim的问题,因此请注意,这不能直接应用于此处可能会有所帮助。
/\%(X.*\)\@<!X\%(.*X\)\@!/
/\%(hr\..*\)\@<!hr\.\%(.*hr\.\)\@!/