【问题标题】:grep: matching on literal "+"grep:匹配文字“+”
【发布时间】:2023-04-06 16:45:01
【问题描述】:

我需要在我的 sql 脚本(即 Oracle 外连接表达式)中查找出现的“(+)”。意识到“+”、“(”和“)”都是特殊的正则表达式字符,我尝试了:

grep "\(\+\)" *

现在这确实返回了“(+)”的出现,但也返回了其他行。 (似乎任何在同一行上带有打开和关闭括号的东西。)回想一下,括号仅对扩展的 grep 是特殊的,我尝试了:

grep "(\+)" * grep "(\\+)" *

这两个都只返回包含“()”的行。所以假设“+”不能被转义,我尝试了一个老把戏:

grep "([+])" *

这行得通。我使用非正则表达式工具交叉检查了结果。

问题:有人能解释一下“+”字符到底是怎么回事吗?有没有更简洁的方式来匹配“(+)”?

(我正在使用 cygwin grep 命令。)

编辑:感谢您的解决方案。 -- 现在我看到,根据 Bruno 引用的 GNU grep 手册,“\+”在 basic 表达式中使用时赋予“+”扩展的含义,因此匹配一个或多个 "("s 后跟一个 ")"。在我的文件中总是“()”。

【问题讨论】:

    标签: regex cygwin grep


    【解决方案1】:

    GNU grep(包含在 Cygwin 中)支持正则表达式的两种语法:基本和扩展。 grep 使用基本正则表达式,egrepgrep -E 使用扩展正则表达式。与grep manual 的基本区别如下:

    在基本的正则表达式中,元字符?+{|()失去了它们的特殊含义;而是使用反斜杠版本\?\+\{\|\(\)

    由于您想要字符( + )普通含义,因此以下两种形式中的任何一种都应该适合您的目的:

    grep "(+)" *       # Basic
    egrep "\(\+\)" *   # Extended
    

    【讨论】:

    • 我刚刚发现你的第二个例子有效,而不是第一个。唔。 cygwin grep 破了吗??
    • grep --version 的输出是什么?对我来说,它适用于“grep (GNU grep) 2.5.1”。
    • 嗯,这里也一样:grep (GNU grep) 2.5.1
    • 下面的不行吗? echo -e "(+)\n()\n+" | grep "(+)"
    • 啊,这行得通! (我没有意识到你把 \ 放在 + 前面)所以,“+”也是一个扩展的正则表达式。我固执地认为这是一个基本的。谢谢。
    【解决方案2】:

    您可能需要添加一些反斜杠,因为 shell 正在吞噬它们。

    ETA:实际上,我刚刚在 Cygwin 上尝试过,grep "(+)" 似乎可以满足您的需求。

    【讨论】:

    • 我刚刚尝试了 grep -E "(\+)" *,并且有效。所以这似乎不是一个shell问题。 cygwin非扩展正则表达式会被破坏吗??
    • 太糟糕了,只能接受一个答案。布鲁诺引导我完成了它,但你也是正确的。我忘记了“+”也只对扩展正则表达式是特殊的。
    • 不,这些字符在双引号字符串中应该没问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-10-15
    • 1970-01-01
    • 1970-01-01
    • 2021-09-19
    • 1970-01-01
    • 2012-11-23
    相关资源
    最近更新 更多