【问题标题】:Matching arbitrary number of digits using grep regex使用 grep 正则表达式匹配任意位数
【发布时间】:2013-02-02 07:05:01
【问题描述】:

我有一个文件,其中包含如下所示的行

data
datalater
983290842
Data387428later
datafhj893724897290384later
4329804928later

我想要做的是使用正则表达式来匹配任何以数据开头并以稍后结尾的行并且之间有数字。到目前为止,这是我编造的:

^[D,d]ata[0-9]*later$ 

但是,输出包括所有数据后行。我想我可以稍后通过管道输出和 grep -v data,但我觉得单个表达式应该可以解决问题。

【问题讨论】:

    标签: regex grep


    【解决方案1】:

    使用+ 而不是*

    + 至少匹配前面的一个或多个。
    * 匹配零个或多个。

    ^[Dd]ata[0-9]+later$
    

    在 grep 中你需要对 + 进行转义,我们可以使用 \d,它是一个字符类,匹配单个数字。

    ^[Dd]ata\d\+later$
    

    在您的示例文件中,您还有一行:

    datafhj893724897290384later
    

    由于数据和数字之间存在字母,因此目前不会匹配。我们可以通过添加[^0-9]* 来解决这个问题,以匹配数据之后直到数字的任何内容。

    我们的最终命令是:

    grep '^[Dd]ata[^0-9]*\d\+later$' filename
    

    【讨论】:

    • 当使用这个表达式或@Eric 时,我没有得到输出结果。这是我正在使用的: grep ^[D,d]ata[0-9]+later$ 文件名
    • 即使作为复制/粘贴,仍然没有骰子。
    • 文件内容也要有空格/换行符$ cat test2 datadata datalater data98349248later datadhsd90834092823later
    • 如果有空格,您能否更新问题中的示例文件,以便我可以更新正则表达式。它目前适用于您提供的示例。
    • 8 年后,但是关于需要转义的 + 的花絮是黄金(并且在“我需要这样做但 Linux 不是我的本地环境”的情况下通过反复试验找到非常不直观)。
    【解决方案2】:

    您使用 * 限定符匹配零个或多个数字。试试

    ^[Dd]ata\d+later$
    

    相反。您还在字符串的开头找到逗号(例如“,ata1234later”)。 \d 是查找任何数字字符的快捷方式。所以我也改变了这些。

    【讨论】:

    • 我希望这能显示输出,但不会产生任何结果。查看我对@Tom 的回复
    【解决方案3】:

    您应该使用“+”(表示一个或多个)而不是“*”(表示零、一个或多个)

    【讨论】:

    • 哎呀,汤姆在我写几个答案的时候回答了,他明白了!
    【解决方案4】:

    使用 Cygwin,上述命令不起作用。我不得不修改上面给出的命令以获得想要的结果。

    $ cat > file.txt <<EOL
    > data
    > datalater
    > 983290842
    > Data387428later
    > datafhj893724897290384later
    > 4329804928later
    > EOL
    

    我总是喜欢确保我的文件符合我的预期:

    $ cat file.txt
    data
    datalater
    983290842
    Data387428later
    datafhj893724897290384later
    4329804928later
    
    $
    

    我需要使用 -P 标志运行 Perl 风格的表达式。这意味着我不能使用[^0-9]+,@Tom_Cammann 恰当地指出了它的必要性。相反,我使用了.*,它匹配任何不匹配模式下一部分的字符序列。这是我的命令和输出。

    $ grep -P '^[Dd]ata.*\d+later$' file.txt
    Data387428later
    datafhj893724897290384later
    
    $
    

    我希望我能更好地解释为什么需要 Perl 表达式,但我只知道 Cygwin 的 grep 工作方式有点不同。

    系统信息

    $ uname -a
    CYGWIN_NT-10.0 A-1052207 2.5.2(0.297/5/3) 2016-06-23 14:29 x86_64 Cygwin
    

    我之前回答的结果

    $ grep '^[Dd]ata[^0-9]*\d\+later$' file2.txt
    
    $ grep '^[Dd]ata\d+later$' file2.txt
    
    $ grep -P '^[Dd]ata[^0-9]*\d\+later$' file2.txt
    
    $ grep -P '^[Dd]ata\d+later$' file2.txt
    Data387428later
    
    $
    

    【讨论】:

    • 尽管我使用的是 MinGW,但您的回答对我也有帮助。根据stackoverflow.com/questions/771756/…,git-bash 似乎“它取决于 MSYS DLL,它是 Cygwin DLL 的一个分支”,这可以解释一切
    【解决方案5】:

    “+”语法仅适用于扩展正则表达式,不适用于标准 grep。
    至少,这是我在 RHEL 上的经验。

    要使用扩展正则表达式,运行 egrep 或传递“-E”/“--extended-regexp” 例子...

    标准 grep

    echo abc123n1  | grep "abc[0-9]+n1"
    <no output>
    

    egrep

    echo abc123n1  | egrep "abc[0-9]+n1"
    abc123n1
    

    grep 与 -E

    echo abc123n1  | grep -E "abc[0-9]+n1"
    abc123n1
    

    HTH

    【讨论】:

      【解决方案6】:

      ?动机

      其余答案不适用于所有系统


      ?️ 要求

      • grep
      • 选项:--extended-regexp
      • 字符组,又名:[:group:]
      • 匹配上述一项或多项,即:+
      • 可选择设置为开始或结束:^whatever$

      ? 命令

      grep --extended-regexp "[[:group:]]+"


      ?️ 组

      • 阿尔法
      • 空白
      • cntrl
      • 数字
      • 图表
      • 降低
      • 打印
      • 空间
      • xdigit

      【讨论】:

        猜你喜欢
        • 2017-02-09
        • 1970-01-01
        • 1970-01-01
        • 2013-10-08
        • 1970-01-01
        • 2011-08-05
        • 2020-12-01
        • 1970-01-01
        相关资源
        最近更新 更多