如何打印字符串中最长的数字?

如何打印字符串中最长的数字?

我正在寻找一种打印字符串中最长数字的方法。

例如:如果我有字符串

212334123434test233

我怎样才能打印

212334123434

注意:我正在寻找最长的连续数字序列,而不是数字上更高的值。


编辑:谢谢大家的回答。对于这个问题的回答非常热烈。我将@HaukeLaging 的帖子标记为已接受的答案,因为它非常适合我的具体情况,但我想指出所有答案都同样有效。有几种不同的选择来解决问题总是很棒的。

答案1

我相信你也可以用grepsort、来做到这tail一点。以下是一些示例字符串。

$ echo <str> | grep -oP "\d+" | sort -n | tail -1

<str>我们的字符串在哪里有问题。

例子

$ set -o posix; set | grep "str[0-9]"
str0=212334123434test233
str1=212334123434test233abc44
str2=233test212334123434
str3=a212334123434test233abc44
str4=a91234b212334123434abc

现在,如果我grep ...依次通过我的命令运行这些。

$ echo $str0 | grep -oP "\d+" | sort -n | tail -1
212334123434
$ echo $str1 | grep -oP "\d+" | sort -n | tail -1
212334123434
$ echo $str2 | grep -oP "\d+" | sort -n | tail -1
212334123434
$ echo $str3 | grep -oP "\d+" | sort -n | tail -1
212334123434
$ echo $str4 | grep -oP "\d+" | sort -n | tail -1
212334123434

此方法的工作原理是选择所有数字序列的子字符串。然后,我们对输出进行数字排序,sort -n,然后使用 获取列表中的最后一个值tail -1。这将是最长的子串。

tail -1您可以通过关闭并重新运行其中一个示例来了解它是如何工作的:

$ echo $str4 | grep -oP "\d+" | sort -n
91234
212334123434

以零开头的字符串

上述方法适用于我能想到的所有情况,除了一种情况。@terdon 在聊天中提到这种情况挫败了上述方法。

  • 0000000000001
  • 2

因此,要解决这个问题,您需要稍微改变策略。仍然可以利用上述方法的核心,但是我们也需要将字符数注入到结果中。这使得 sort 能够按字符串中的字符数及其值对结果进行排序。

$ for i in $(echo $str0 | grep -oP "\d+");do a=$(echo "$i" | wc -c); \
    echo "$a $i"; done | sort -n | tail -1 | cut -d" " -f2

结果:

$ echo $str0
0000000000001a2test

$ for i in $(echo $str0 | grep -oP "\d+");do a=$(echo "$i" | wc -c); \
    echo "$a $i"; done | sort -n | tail -1 | cut -d" " -f2
0000000000001

您可以通过利用 Bash 的功能来压缩它,使用 确定变量的长度${#var}

$ for i in $(echo $str0 | grep -oP "\d+");do echo "${#i} $i"; done | \
    sort -n | tail -1 | cut -d" " -f2
0000000000001

使用`grep -P

我选择使用grep -P ...上面的方法,因为作为一名 Perl 开发人员,我喜欢这样表示所有数字的类语法:\d+, 而不是[[:digit:]]\+or [0-9]\+。但对于这个特定问题来说,它并不是真正需要的。你可以像这样轻松地换掉grep我用过的:

$ .... grep -o "[0-9]\+" ....

例如:

$ for i in $(echo $str0 | grep -o "[0-9]\+");do echo "${#i} $i"; done | \
    sort -n | tail -1 | cut -d" " -f2
0000000000001

答案2

解决方案perl

echo 212334123434test233abc44 |
perl -nle 'print ((
    map { $_->[0] }
    sort{ $a->[1] <=> $b->[1] }
    map { [$_,length] }
    split /\D+/, $_)[-1]
    )'
212334123434

参考

答案3

echo 212334123434test233abc44 | 
awk '{gsub("[^0-9]+","\n"); print;}' | 
awk '{ if (length($0) > max) {max = length($0); maxline = $0} } 
  END { print maxline }'

212334123434

答案4

这是另一种可以处理小数和整数的 Perl 方法:

echo "0.212334123434test233" | 
 perl -lne 'while(/([\d.]+)/g){$max=$1 if length($1) > length($max)} print $max'

请注意,到目前为止发布的答案都不会处理小数,并且由于您指定您想要最长的数字而不是数字上最大的数字,我假设您实际上需要小数点。

解释

  • perl -lne-n意思是“逐行读取输入,并-e在其上运行给出的脚本”。为每个调用添加-l换行符print(以及此处不相关的其他内容)。
  • while(/([\d.]+)/g):迭代所有数字(\d意味着[0-9],因此[\d.]将匹配数字 和.。如果您还想查找负数,请添加-。括号捕获匹配的字符串,以便$1在下一步中使用。
  • $max=$1 if length($1) > length($max):如果当前匹配的长度大于迄今为止最长的($max)将匹配保存为$max
  • print $max:打印找到的最长的数字字符串。这将被执行while 循环结束,所以在找到所有数字之后。

相关内容