仅匹配数字的正则表达式

3
我有困难理解我的bash shell中的正则表达式到底在做什么。
我有一个字符串abcde 12345 67890testing,我想使用sed从这个字符串中提取12345
然而,在给定的字符串上使用sed -re 's/([0-9]+).*/\1/'会给我返回abcde 12345
另外,使用sed -re 's/([\d]+).*/\1/'实际上只会提取abcd
我是否错误地认为表达式[0-9][\d]只捕获数字?我不知道为什么abcd被捕获了,而字符串67890没有被捕获。此外,我想知道为什么我的第一个查询中空格被捕获了?
此外,sed -re 's/^.*([0-9]+).*/\1/'返回0。在这种情况下,我完全不理解正则表达式在做什么。我认为表达式^.*[0-9]+只会捕获纯数字字符串的第一个实例?但是它只匹配最后一个0。
总之,我想了解我的错误在哪里,以及如何在正则表达式中解决这个问题,而不使用[\s]来隔离第一个数字字符串。

问题在于你的 sed 命令是这样的: "在每一行中,查找一些数字后跟任意数量的字符,并用这些数字替换该匹配项。" 它正在执行指定的操作,即将 12345 67890testing 替换为 12345。相反,你想要用空白替换初始匹配项。不幸的是,据我所知,在 sed 表达式的开头放置一个非贪婪的 .*? 的方法是不存在的,内联 Perl 或 Ruby 可能是更好的选择。 - chrylis -cautiouslyoptimistic-
4个回答

3
sed -E 's/([0-9]+).*/\1/g'  <<< "$s" 

上述命令的意思是:查找一个数字序列,紧跟着其他字符,并用该数字序列替换它。因此,它匹配 12345 67890testing 并将其替换为 12345
最终的字符串将是 abcd 12345
如果您只想获取 12345,则应使用 grep 命令。
egrep -o '[0-9]+ ' <<< "$s"

你可以使用sed命令:

sed -E 's/[a-zA-Z ]*([0-9]+).*/\1/g'  <<< "$s"

这将删除数字前面的字母。

对于我的最后一次尝试,使用贪婪表达式.*是否会吃掉字符串的其余部分,直到只剩下0?似乎不可能使用贪婪表达式来删除问题前面的abcde部分,是这样吗? - Gin
如果您使用 .*([0-9]+).,它只会匹配最后一个数字,因为 + 表示 1 或更多,所以它将选择最小值。如果您确切地知道数字序列的长度,可以使用 .([0-9]{5}) .*。在 ) 和 . 之间必须有一个空格。 - drolando

1

您可以使用:

sed 's/^\([0-9]*\).*$/\1/g' <<< "$s"
12345

否则修改您的sed命令:
sed 's/\([0-9]\+\).*/\1/g' <<< "$s"
12345

您需要在sed中转义+(和),而不使用扩展正则表达式标志(-r或-E)。

使用-r,它将是:

sed -r 's/([0-9]+).*/\1/g' <<< "$s"
12345

更新: 实际上您不需要任何外部工具来完成此操作,因为您可以使用BASH自身的正则表达式功能来完成此操作:

[[ "$s*" =~ ^([0-9]+) ]] && echo "${BASH_REMATCH[1]}"
12345

谢谢您的回复。然而,使用 sed -r 's/([0-9]+).*/\1/g' <<< "$s" 将会给我返回 abcd 12345。我不确定它是如何捕获 abcd 的。 - Gin
sed -r 's/([0-9]+).*/\1/g' <<< "$s" 给我返回了 12345 - anubhava
1
你能解释一下使用here string的想法吗?据我所知,这只是在Bash变量s的内容上运行sed表达式,这似乎没有什么帮助。 - chrylis -cautiouslyoptimistic-
让我先问一下,你为什么认为它没有帮助呢?使用 Here-String 可以避免子 Shell 的创建。 - anubhava
1
这是我唯一能让它工作的方法: s="abcde 12345 67890testing" [[ $s =~ ([0-9]+) ]] && echo "${BASH_REMATCH[1]}" - PerseP

0

使用 cut 命令更简单

echo "abcde 12345 67890testing" | cut -d' ' -f2

0

既然其他人已经用sed、grep提供了解决方案,这里是awk代码:

echo "abcde 12345 67890testing"|awk '{for (i=1;i<=NF;i++) if ($i~/^[0-9]+$/) print $i}'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接