【问题标题】:Does Bash support non-greedy regular expressions?Bash 是否支持非贪婪正则表达式?
【发布时间】:2019-08-23 05:12:24
【问题描述】:

我的正则表达式模式为什么不懒惰?它应该捕获第一个数字,而不是第二个。

这是一个有效的 bash 脚本..

#!/bin/bash

text='here is some example text I want to match word1 and this number 3.01 GiB here is some extra text and another number 1.89 GiB'

regex='(word1|word2).*?number[[:blank:]]([0-9.]+) GiB'

if [[ "$text" =~ $regex ]]; then
    echo 'FULL MATCH:  '"${BASH_REMATCH[0]}"
    echo 'NUMBER CAPTURE:  '"${BASH_REMATCH[2]}"
fi

这是输出...

FULL MATCH:  word1 and this number 3.01 GiB here is some extra text and another number 1.89 GiB
NUMBER CAPTURE:  1.89

使用这个online POSIX regex tester 就像我预期的那样懒惰。但是在 Bash 中它是贪婪的。 NUMBER CAPTURE 应该是 3.01,而不是 1.89。

【问题讨论】:

  • 如何让它匹配最短的?
  • 现在可以使用了,谢谢。但是为什么.*? 是未定义的呢?不是说匹配任何东西,只是懒惰(最短的整体匹配)?如果我不知道第一个捕获组和“数字”之间可以出现什么字符怎么办?
  • @deanresin 向量词添加问号(如.*?)以使其不贪婪是正则表达式语法的Perl扩展,而不是符合POSIX的正则表达式系统将支持的东西。该正则表达式测试器声称是 POSIX,但实际上只有 PCRE (perl) 和 Javascript 选项,而不是 POSIX 基本或扩展正则表达式。
  • @GordonDavisson 谢谢。这消除了很多混乱。我绝对习惯了与 PHP 一起使用的那个(可能与 PERL 相同)。
  • @oguzismail 太疯狂了,没有解决方案“匹配任何东西,但取最短”。

标签: regex bash non-greedy posix-ere


【解决方案1】:

Wrt .*?,POSIX 标准说

多个相邻重复符号(“+”、“*”、“?”和间隔)的行为会产生未定义的结果。

关于贪心匹配,它说:

如果模式允许可变数量的匹配字符,因此从该点开始有多个这样的序列,则匹配最长的这样的序列。

在这种特殊情况下,您可以改用[^&]*

text='here is some example text I want to match word1 and this number 3.01 GiB here is some extra text and another number 1.89 GiB'
regex='(word1|word2)[^&]*number[[:blank:]]([0-9.]+) GiB'
if [[ "$text" =~ $regex ]]; then
    echo 'FULL MATCH:  '"${BASH_REMATCH[0]}";
    echo 'NUMBER CAPTURE:  '"${BASH_REMATCH[2]}";
fi

输出:

FULL MATCH:  word1 and this number 3.01 GiB
NUMBER CAPTURE:  3.01

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-27
    • 2010-10-20
    • 2013-02-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多