Regex 使用grep查找关键字,然后列出以下字符,直到下一个;性格

Regex 使用grep查找关键字,然后列出以下字符,直到下一个;性格,regex,grep,osx-yosemite,Regex,Grep,Osx Yosemite,我有一个长长的化学条件列表,格式如下: 0.2M sodium acetate; 0.3M ammonium thiosulfate; 摩尔浓度可通过多种方式列出: x.xM, x.x M, x M 其中x位数不同。我想做两件事,使用grep选择这些数字,然后只列出以下字符,直到。因此,如果我在上面的示例中选择0.2M,我希望能够列出醋酸钠 为了进行选择,我尝试了以下方法: grep '[0-9]*.[0-9]*[[:space:]]*M' file 0.05MRbCl+MgCl2; 所

我有一个长长的化学条件列表,格式如下:

0.2M sodium acetate; 0.3M ammonium thiosulfate;
摩尔浓度可通过多种方式列出:

x.xM, x.x M, x M
其中
x
位数不同。我想做两件事,使用grep选择这些数字,然后只列出以下字符,直到
。因此,如果我在上面的示例中选择
0.2M
,我希望能够列出
醋酸钠

为了进行选择,我尝试了以下方法:

grep '[0-9]*.[0-9]*[[:space:]]*M' file
0.05MRbCl+MgCl2;
所以有任意数量的数字和空格,但它总是以
M
结尾。问题是,它还选择以下选项:

grep '[0-9]*.[0-9]*[[:space:]]*M' file
0.05MRbCl+MgCl2;
我不太清楚为什么选择这个。理想情况下,我希望选择
0.05M
,然后列出
RbCl+MgCl2
。我怎样才能做到这一点


(系统是OS X Yosemite)

它与之匹配,因为:
[0-9]*
匹配
0

匹配任何字符(在本例中,这是
,但您可能打算转义它)
[0-9]*
匹配
05

[[:space:][]*
匹配
05
M

M
匹配
M

至于如何做你想做的事情:我认为如果你不想在输出中打印数字,这需要一个lookback断言或打印特定捕获组的能力,这听起来像是OSX的
grep
不支持。不过,您可以使用类似的方法和功能稍强的工具:

$ cat test.txt 
0.2M sodium acetate; 0.3M ammonium thiosulfate;
0.05MRbCl+MgCl2;
1.23M dihydrogen monoxide;
45 M xenon quadroxide;

$ perl -ne 'while (/([0-9]*\.)?[0-9]+\s*M\s*([^;]+)/g) { print "$2\n"; }' test.txt 
sodium acetate
ammonium thiosulfate
RbCl+MgCl2
dihydrogen monoxide
xenon quadroxide
写出后,正则表达式是:
([0-9]*\)?
可选部分数字和小数点
[0-9]+
一个或多个数字
\s*M\s*
字母M,周围有空格

([^;]+)
下一个分号之前的所有字符(您要打印的内容)

使用GNU awk进行多字符
RS
gensub()
\s

$ awk -vRS=';\\s*' -vm='0.2M' 'm==gensub(/\s*([0-9.]+)\s*M.*/,"\\1M","")' file
0.2M sodium acetate

$ awk -vRS=';\\s*' -vm='0.05M' 'm==gensub(/\s*([0-9.]+)\s*M.*/,"\\1M","")' file
0.05MRbCl+MgCl2