Regex sed 4.2.2中的数字匹配错误?

Regex sed 4.2.2中的数字匹配错误?,regex,linux,bash,ubuntu,sed,Regex,Linux,Bash,Ubuntu,Sed,我不是sed的新手,但我也很难相信这个古老的产品中有一个可怕的错误,所以我只想通过多看一眼来检查我是否在做一些愚蠢的事情 我试图从URL字符串中提取一组数字,但sed似乎在匹配每个字符以及数字的范围 bdetweiler@HPSin:~$ echo "www.blah.com/012345/moreblah.html" | sed -e 's/\([[:digit:]]*\)/!\1/g' !w!w!w!.!b!l!a!h!.!c!o!m!/!012345/!m!o!r!e!b!l!a!h!.!

我不是sed的新手,但我也很难相信这个古老的产品中有一个可怕的错误,所以我只想通过多看一眼来检查我是否在做一些愚蠢的事情

我试图从URL字符串中提取一组数字,但sed似乎在匹配每个字符以及数字的范围

bdetweiler@HPSin:~$ echo "www.blah.com/012345/moreblah.html" | sed -e 's/\([[:digit:]]*\)/!\1/g'
!w!w!w!.!b!l!a!h!.!c!o!m!/!012345/!m!o!r!e!b!l!a!h!.!h!t!m!l!
bdetweiler@HPSin:~$ echo "www.blah.com/012345/moreblah.html" | sed -e 's/\([0-9]*\)/!\1/g'
!w!w!w!.!b!l!a!h!.!c!o!m!/!012345/!m!o!r!e!b!l!a!h!.!h!t!m!l!
bdetweiler@HPSin:~$ echo "www.blah.com/012345/moreblah.html" | sed -e 's/.*\([0-9]*\).*/!\1/g'
!
bdetweiler@HPSin:~$ echo "www.blah.com/012345/moreblah.html" | sed -e 's/.*\([[:digit:]]*\).*/!\1/g'
!


bdetweiler@HPSin:~$ sed --version 
sed (GNU sed) 4.2.2

bdetweiler@HPSin:~$ uname -a
Linux HPSin 3.13.0-62-generic #102-Ubuntu SMP Tue Aug 11 14:29:36 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
另一方面,白鹭很好地将其拉出:

我是否做错了什么,或者我可能在sed中看到了一个可怕的错误

编辑2015-10-29 07:35 这似乎不是sed特有的。Perl给了我同样的问题:

echo -n "www.blah.com/012345/moreblah.html" | perl -pe "s/.*([0-9]+).*/\1/g"
5

至少1位,如果不是,则所有内容都与模式对应:-)


使用
+
而不是
*
(如果不支持
+
,则使用
[0-9][0-9]*
)。否则,它将在每个位置匹配空字符串。这是有意义的,但事实似乎并非如此。sed-e的s/*([0-9]+).*/\1/g'只生成整个字符串(www.blah.com/012345/moreblah.html)和sed-e的/*([0-9][0-9]*)。/\1/g'给出数字字符串(!5)中的最后一个数字。将开头的
*
更改为
[^0-9]*
*
太贪婪,干扰了数字字符串的匹配。至于
+
,它不在BRE的POSIX标准中,而是为ERE定义的。一些实现使用
\+
扩展了BRE,或者使用一个标志扩展了sed以使用ERE。由于OP使用的是GNU sed,您可以使用
\+
而不是
\{1,\}
,或者使用
sed-r/([[:digit:]+])保存更多字符\1/g'
。你说得对,我只是尝试使用更通用的格式,以便在成本较低的情况下允许几乎任何sed工作。对于较小的sed版本
sed-r's/[0-9]+/&/g
谢谢你在-r标志上的提示,但不要掷骰子。正在做sed-r/([:digit:][]+)/\1!/实际上,g'用我的感叹号(www.blah.com/!012345!/moreblah.html)包围了目标字符串,但是当我尝试用目标字符串替换所有内容时,它只捕获最后一个数字:sed-r的s/*([[:digit:]+).*/\1克!5@bdetweiler这是因为第一个
*
试图尽可能地获取最大的值。可以尝试使用
*[^[:digit:]
代替,假设在数字之前至少有一个字符,这会产生预期的效果,尽管它肯定不像我预期的那样简单:
echo“www.blah.com/012345/moreblah.html”| sed-r的/[^[:digit:]*/g'
echo "www.blah.com/012345/moreblah.html" | sed -e 's/\([[:digit:]]\{1,\}\)/!\1/g'