Unix shell:带有正则表达式的子字符串

Unix shell:带有正则表达式的子字符串

我有这样的文字:

1234

我想使用正则表达式来选择除第一个数字(在本例中为 1)之外的所有数字 - 因此选择的模式

234

我怎样才能做到这一点?我不能使用变量,只能使用正则表达式。而且我也无法删除第一个数字。只有一个正则表达式选择除第一个数字之外的所有字符串。

答案1

将正则表达式应用于字符串参数的标准命令是expr使用其:运算符。它理解标准基本正则表达式。它根据正则表达式是否匹配来输出 1 或 0,除非正则表达式至少有一个捕获组,在这种情况下,它会输出与第一个捕获组匹配的内容。expr的一个特点:是正则表达式隐式地锚定在开头,就好像它以 开头一样^。所以:

text=1234
expr "x$text" : "x.\(.*\)"

我们在文本和正则表达式上都加上(任意)前缀,否则如果 的内容恰好是一个运算符,或者至少是某个运算符,x则命令将失败,这些运算符会出现问题,具体取决于实现。例子:$textexprexpr

$ text='('
$ expr "$text" : ".\(.*\)"
expr: syntax error: expecting ')' instead of ‘.\\(.*\\)’
$ expr "x$text" : "x.\(.*\)"

$ text=index
$ expr "$text" : ".\(.*\)"
0
$ expr "x$text" : "x.\(.*\)"
ndex

第一个.匹配未输出的第一个字符,$text因为它不在捕获组内。然后我们捕获其余.*的 0 个或更多字符,尽可能多的用于输出。

$text如果正则表达式不匹配(为空或以无法解释为字符的内容开头)或者如果输出是数字0(并且根据expr实现,其中一些不同的值),退出状态将为非零其他拼写,如00, -0...) 或空字符串。

但无论如何,您不需要expr为此运行或使用正则表达式。标准 shell 参数扩展运算符可以做到这一点:

text=1234
printf '%s\n' "${text#?}"

Where扩展到匹配的前导部分已被删除的位置${var#pattern}的内容。$varpattern

答案2

假设文本在文件中file,以下sed命令将删除文件每行的第一个数字并输出结果:

sed 's/[[:digit:]]//' file

测试:

$ cat file
123
1234
alpha123
a1b2c3
$ sed 's/[[:digit:]]//' file
23
234
alpha23
ab2c3

如果字符串位于变量中,则实际上不需要正则表达式。就足够了

${string/[[:digit:]]/}

bash

$ string=alpha123
$ printf '%s\n' "${string/[[:digit:]]/}"
alpha23

如果您只想删除出现在第一个位置的数字,则可以使用标准参数替换

${string#[[:digit:]]}

$ string=1234
$ printf '%s\n' "${string#[[:digit:]]}"
234

相关内容