使用grep regex匹配任意位数

问题描述 投票:2回答:4

我有一个文件,其中的行看起来类似如下

data
datalater
983290842
Data387428later
datafhj893724897290384later
4329804928later

我要做的是使用正则表达式来匹配任何以数据开头并以后结束的行,并且中间有数字。这是我到目前为止所编造的内容:

^[D,d]ata[0-9]*later$ 

但是输出包括所有数据行。我想我可以管道输出和grep -v datalater,但我觉得单个表达式应该可以解决问题。

regex grep
4个回答
3
投票

使用+而不是*

+匹配前面的至少一个或多个。 *匹配零或更多。

^[Dd]ata[0-9]+later$

在grep中你需要逃离+,我们可以使用\d这是一个字符类并匹配单个数字。

^[Dd]ata\d\+later$

在您的示例文件中,您还有一行:

datafhj893724897290384later

由于数据和数字之间存在字母,因此目前不会匹配。我们可以通过添加一个[^0-9]*来匹配任何数据后的数字直到数字。

我们的最终命令是:

grep '^[Dd]ata[^0-9]*\d\+later$' filename

2
投票

您使用*限定符匹配零个或多个数字。尝试

^[Dd]ata\d+later$

代替。你也在字符串的开头找到逗号(例如“,ata1234later”)。而\ d是查找任何数字字符的快捷方式。所以我也改变了。


1
投票

你应该放一个“+”(意思是一个或几个)而不是“*”(这意味着零,一个或几个


0
投票

使用Cygwin,上面的命令不起作用。我不得不修改上面给出的命令以获得所需的结果。

$ cat > file.txt <<EOL
> data
> datalater
> 983290842
> Data387428later
> datafhj893724897290384later
> 4329804928later
> EOL

我总是希望确保我的文件符合我的期望:

$ cat file.txt
data
datalater
983290842
Data387428later
datafhj893724897290384later
4329804928later

$

我需要使用-P标志运行Perl样式的表达式。这意味着我无法使用[^0-9]+,它的必要性@Tom_Cammann恰如其分地指出。相反,我使用.*匹配任何不匹配模式的下一部分的字符序列。这是我的命令和输出。

$ grep -P '^[Dd]ata.*\d+later$' file.txt
Data387428later
datafhj893724897290384later

$

我希望我能更好地解释为什么需要Perl表达式,但我只知道Cygwin的grep的工作方式有点不同。

系统信息

$ uname -a
CYGWIN_NT-10.0 A-1052207 2.5.2(0.297/5/3) 2016-06-23 14:29 x86_64 Cygwin

我之前的答案结果

$ grep '^[Dd]ata[^0-9]*\d\+later$' file2.txt

$ grep '^[Dd]ata\d+later$' file2.txt

$ grep -P '^[Dd]ata[^0-9]*\d\+later$' file2.txt

$ grep -P '^[Dd]ata\d+later$' file2.txt
Data387428later

$
热门问题
推荐问题
最新问题