Regex BASH正则表达式{}
我想我对Regex BASH正则表达式{},regex,bash,Regex,Bash,我想我对{3,5}部分的工作原理有错误的想法 据我所知,它指定了数字返回搜索结果必须符合的范围 例如,3,5表示返回搜索的3-5位数字。经过一些实验,我意识到我的逻辑并不完全正确 它似乎从3-5个字符开始应用,然后是8、9和10个字符 我是不是错过了一个模式?或者更简单地说,有人能向我解释一下背后的逻辑吗?它只是3的倍数,还是5的倍数?包括3-5的范围?我真的很困惑。谢谢 user@matrix:~>echo 1234567891234 | grep'[0-9]{3,5}' 1234567891
{3,5}
部分的工作原理有错误的想法
据我所知,它指定了数字返回搜索结果必须符合的范围
例如,3,5
表示返回搜索的3-5位数字。经过一些实验,我意识到我的逻辑并不完全正确
它似乎从3-5个字符开始应用,然后是8、9和10个字符
我是不是错过了一个模式?或者更简单地说,有人能向我解释一下背后的逻辑吗?它只是3的倍数,还是5的倍数?包括3-5的范围?我真的很困惑。谢谢
user@matrix:~>echo 1234567891234 | grep'[0-9]{3,5}'
1234567891234
上面的匹配成功,它包含12个字符…您可以使用
-o
选项来可视化grep的工作方式:
echo 1234567891234 | grep -o '[0-9]\{3,5\}'
输出:
12345
67891
234
-o
将在每次匹配输出后添加新行。如果没有该选项,grep将只打印匹配发生的整行内容,即输入字符串本身。这样,您将无法看到grep与字符串的精确匹配程度
但现在您可以看到,grep在该行中找到了多个匹配项,分别是5位字符串的2倍和3位字符串的1倍
另外,除非使用
-E
选项,否则在{}
括号前面需要斜杠。假设{3,5}定义的是前面类中所选字符的重复-重复3到5次(包括3到5次)。
您还可以执行类似于{3,}
的操作,这意味着“至少3次”
使用-Ex
选项,E
-这样您就不必在括号和x
之前使用斜杠来标记整行:
[alfasin@otrs ~]$ echo 1234567891234 | grep -Ex '[0-9]{3,5}'
[alfasin@otrs ~]$ echo 1234567891234 | grep -Ex '[0-9]{3,13}'
1234567891234
从grep手册:
-E、 --扩展regexp
将模式解释为扩展正则表达式(见下文)。(-E由POSIX指定。)
-x、 --行regexp
仅选择与整行完全匹配的匹配项。(-x由POSIX指定。)
它的工作原理与您所写的完全相同:
grep '[0-9]\{3,5\}' - Is there 3 to 5 sequential numeric characters in this string?
如果字符串是1234567891234
,则其中有一个子字符串包含3-5个数字字符
如果您只对只包含3-5个数字字符且不超过5个字符的字符串感兴趣,则必须在正则表达式中设置一些边界。您还应该使用-E
标志,该标志使用更现代版本的正则表达式:
$ echo 12345678901234 | grep -E "(^|[^0-9])[0-9]{3,5}([^0-9]|$)"
这不会打印任何内容,但会:
$ echo 1234 | grep -E "(^|[^0-9])[0-9]{3,5}([^0-9]|$)"
这是:
$ echo 12345aaa6789aaa01234 | grep -E "(^|[^0-9])[0-9]{3,5}([^0-9]|$)"
第一个(^ |[^0-9])
要么在行首(即前导^
),要么在字符0-9之外的任何位置。(这是[^0-9]
)。在扩展正则表达式中使用(…|…)
表示左侧的表达式或右侧的表达式。结尾([^0-9]|$)
也是如此,表示非数字或行尾
中间是[0-9]{3,5}
(扩展表达式不需要反斜杠)。这表示在3到5位之间。而且,由于它的任意一侧都由非数字或字符串的开头或结尾绑定,因此这将满足您的需要
有几件事:
$ echo 12345aaa6789aaa01234 | grep -E "(^|[^0-9])[0-9]{3,5}([^0-9]|$)"
及
当您使用特定的正则表达式时,它将匹配输入字符串中的前5个字符(有关可视化信息,请参阅)。一旦
grep
找到匹配项,它就会停止处理并返回匹配行。除了那场比赛之外,它甚至没有注意任何事情
如果您正在寻找只匹配3-5位数的孤立序列的内容,请尝试以下正则表达式:
\b[0-9]{3,5}\b
“\b
”将匹配单词边界,表示单词字符(字母、数字等)和非单词字符(空格、标点符号等)之间的转换。这将为1234
生成匹配,但不会为12
或1234567891234
生成匹配
您还可以使用更强大的方法来确保您的比赛前后没有数字。然而,grep对lookaround的支持似乎并不完整,因此您可能不得不使用类似perl的东西来代替它。
grep--line regexp'[0-9]\{3,5\}'
?如果您不锚定匹配,它只应用于子字符串——在本例中,意味着在较大的字符串中的任何位置都有3-5个字符。听起来你想要^[0-9]\{3,5\}$
。顺便说一句,这与Bash无关。虽然Bash也有内置的正则表达式功能,但它们的行为与您在这里研究的grep
截然不同。@nosid--line regexp
是-x
的同义词(反之亦然):)好吧。。。匹配项不是grep
通常输出的内容,整行是到stdout的内容,这意味着对于123456789123
(匹配两次,但不能对最后两个字符执行任何操作),整行仍将转到输出。所以,这不是“合并匹配”,而是告诉匹配的行至少一次。@Wrikken我知道,但看起来是这样的,这让你的答案很模糊。作为一个新手,我将其理解为:所有匹配项都不带换行符地转到标准输出,只需在其中添加一个-o
来添加分隔符。我会避免这么容易误解答案。@Wrikken我已经更新了这个。然而,我不认为我的帖子是戏剧性的误导。至少我是唯一一个提到KarolyHorvath的人请解释一下。请注意,问题是关于理解的,从-o
获得输出很容易理解发生了什么。不,我不会删除多行输出的注释。如果您现在用-E
回答问题,您不应该编辑该问题。我已经用-E
得到了答案,但后来更改了它
$ grep -E "(^|[^\d])\d{3,5}([^\d]|$)"<<<"12345aaa6789aaa01234"
\b[0-9]{3,5}\b