如何从字符串中提取数字?

Posted

技术标签:

【中文标题】如何从字符串中提取数字?【英文标题】:How to extract numbers from a string? 【发布时间】:2013-07-26 20:37:59 【问题描述】:

我有一个包含路径的字符串

string="toto.titi.12.tata.2.abc.def"

我只想从这个字符串中提取数字。

提取第一个数字:

tmp="$string#toto.titi.*."
num1="$tmp%.tata*"

提取第二个数字:

tmp="$string#toto.titi.*.tata.*."
num2="$tmp%.abc.def"

所以要提取参数,我必须分两步完成。如何一步提取一个数字?

【问题讨论】:

这个问题已经有一段时间了。如果没有一个答案提供您正在寻找的内容,那么您能否更新您的问题以进一步阐明您的要求? echo $string | grep -o -E "[0-9]+" 我认为是最简洁和最容易理解的(大多数人都知道 grep)。来自:***.com/a/52947167/52074 【参考方案1】:

如果您准确地提供了您想要获得的输出,这将更容易回答。如果您的意思是只想从字符串中获取数字,并删除其他所有内容,您可以这样做:

d@AirBox:~$ string="toto.titi.12.tata.2.abc.def"
d@AirBox:~$ echo "$string//[a-z,.]/"
122

如果您澄清一点,我可能会提供更多帮助。

【讨论】:

我更新了我的问题。我想提取 12,然后提取 2。不要同时提取两个数字【参考方案2】:

您可以使用tr 删除所有非数字字符,如下所示:

echo toto.titi.12.tata.2.abc.def | tr -d -c 0-9

【讨论】:

这个输出似乎将所有数字混合在一起,在您的示例中形成122。他们怎么可能分开? 为了将其设置为变量使用- PARAM=`echo toto.titi.12.tata.2.abc.def | tr -d -c 0-9 `【参考方案3】:

使用正则表达式匹配:

string="toto.titi.12.tata.2.abc.def"
[[ $string =~ toto\.titi\.([0-9]+)\.tata\.([0-9]+)\. ]]
# BASH_REMATCH[0] would be "toto.titi.12.tata.2.", the entire match
# Successive elements of the array correspond to the parenthesized
# subexpressions, in left-to-right order. (If there are nested parentheses,
# they are numbered in depth-first order.)
first_number=$BASH_REMATCH[1]
second_number=$BASH_REMATCH[2]

【讨论】:

【参考方案4】:

使用 awk:

arr=( $(echo $string | awk -F "." 'print $3, $5') )
num1=$arr[0]
num2=$arr[1]

【讨论】:

【参考方案5】:

你也可以使用 sed:

echo "toto.titi.12.tata.2.abc.def" | sed 's/[0-9]*//g'

这里,sed 替换了

任何数字([0-9] 类) 重复任意次数 (*) 什么都没有(第二个和第三个/之间什么都没有), 和g 代表全局。

输出将是:

toto.titi..tata..abc.def

【讨论】:

我认为 OP 想要数字,而不是字符串作为输出。 如果您想要数字,请使用 ^ 反转匹配:echo "toto.titi.12.tata.2.abc.def" | sed 's/[^0-9]*//g'【参考方案6】:

参数扩展似乎是当务之急。

$ string="toto.titi.12.tata.2.abc.def"
$ read num1 num2 <<<$string//[^0-9]/ 
$ echo "$num1 / $num2"
12 / 2

这当然取决于$string 的格式。但至少对于您提供的示例,它似乎有效。

这可能优于 anubhava 需要子外壳的 awk 解决方案。我也喜欢 chepner 的解决方案,但正则表达式比参数扩展“更重”(尽管显然更精确)。 (请注意,在上面的表达式中,[^0-9] 可能看起来像一个正则表达式原子,但实际上不是。)

您可以在 bash 手册页中阅读有关此表单或参数扩展的信息。请注意,$string//this/that(以及 &lt;&lt;&lt;)是一种 bashism,与传统的 Bourne 或 posix shell 不兼容。

【讨论】:

取决于$string的格式到底是什么意思?我想不出任何可以打破它的例子。 嘿,这是一个老问题。 :) 此时我唯一能想到的是,如果有额外的数字,比如aa12aa34aa56,并且您只读取两个变量,则尾随数字将添加到最后一个变量中,以空格分隔。如果这是一个问题,那么更好的解决方案可能是将字符串读入数组:read -a nums &lt;&lt;&lt;"$string//[^0-9]/ ".【参考方案7】:

提取所有单独的数字并通过 -

每行管道打印一个数字字
tr '\n' ' ' | sed -e 's/[^0-9]/ /g' -e 's/^ *//g' -e 's/ *$//g' | tr -s ' ' | sed 's/ /\n/g'

细分:

用空格替换所有换行符:tr '\n' ' ' 用空格替换所有非数字:sed -e 's/[^0-9]/ /g' 删除前导空格:-e 's/^ *//g' 删除尾随空格:-e 's/ *$//g' 按顺序将空格压缩为 1 个空格:tr -s ' ' 用换行符替换剩余的空格分隔符:sed 's/ /\n/g'

例子:

echo -e " this 20 is 2sen\nten324ce 2 sort of" | tr '\n' ' ' | sed -e 's/[^0-9]/ /g' -e 's/^ *//g' -e 's/ *$//g' | tr -s ' ' | sed 's/ /\n/g'

会打印出来

20
2
324
2

【讨论】:

【参考方案8】:

您好,添加另一种使用“剪切”的方法,

echo $string | cut -d'.' -f3,5 | tr '.' ' '

这将为您提供以下输出: 12 2

【讨论】:

【参考方案9】:

这是一个简短的:

string="toto.titi.12.tata.2.abc.def"
id=$(echo "$string" | grep -o -E '[0-9]+')

echo $id // => output: 12 2

数字之间有空格。 希望对你有帮助...

【讨论】:

【参考方案10】:

修复换行问题(对于 mac 终端):

cat temp.txt | tr '\n' ' ' | sed -e 's/[^0-9]/ /g' -e 's/^ *//g' -e 's/ *$//g' | tr -s ' ' | sed $'s/ /\\\n/g'

【讨论】:

以上是关于如何从字符串中提取数字?的主要内容,如果未能解决你的问题,请参考以下文章

python中如何从字符串中提取数字?

如何从字符串中提取数字?

如何从字符串中提取简单的数字表达式数字?

c ++如何从具有反斜杠的字符串中提取数字?

Java如何从字符串中提取数字

如何使用 REGEXP sql 从字符串中仅提取 5 位数字