2015-12-15 37 views
3

请考虑以下情况。这是假设的,但是展示了我想要完成的一般事情。格式perl正则表达式捕获组

假设我有一个文件,它有一行或多行。在每一行上,它可能有一个或多个[name] = [value]的实例,其中[name]是一些变量名称,[value]是一些值。进一步假设这些中的每一个都被/[a-zA-Z]+=[0-9]+/匹配。

我想要的是一个perl表达式,它会打印出每个匹配,并以特定的方式进行格式化。我的意图是在命令行上使用它来解析文件中的数据。一个假设的解决方案因为perl实际上并不接受这个语法而变得无效:print m/([a-zA-Z]+)=([0-9]+)/name: \1, value: \2\n/g,它在我们理想的世界的每一行上运行时,会打印出每行匹配的每个匹配,如name:[name], value:[value],每个匹配都在自己的行上。

例如,请考虑此输入文件test.txt:

blah blah count=5 blah i=1 
books=2 blah 
blah fairies=87 water=0 

假设我们然后键入我们的魔法命令为bash中,类似如下:

perl -n -e 'print m/([a-zA-Z]+)=([0-9]+)/name: \1, value: \2\n/g' test.txt 

(这可能是更合理要求对所有返回的匹配进行某种循环,但希望您能明白这一点)。

它会打印以下内容:

name: count, value: 5 
name: i, value: 1 
name: books, value: 2 
name: fairies, value: 87 
name: water, value: 0 

我意识到这个语法实际上并不工作,但我希望尽可能简短地完成同样的事情。我希望能够在命令行中偶尔使用它来查找和格式化文本。我写了自己的ruby脚本,但它有点bug,并且不包含在标准环境中(或者在任何人的环境中,但是我自己的环境中)。任何人都知道一些perl秘密?

+0

一种可能的解决方案可能是如果有一种紧凑的方式来返回一堆匹配,然后对每个匹配应用查找/替换,并将其打印出来。 – Erhannis

回答

7

你非常接近。 ;-)

$ perl -ne 'print "name: $1, value: $2\n" while /([a-zA-Z]+)=([0-9]+)/g;' test.txt 
name: count, value: 5 
name: i, value: 1 
name: books, value: 2 
name: fairies, value: 87 
name: water, value: 0 

编辑:既然你comment似乎表明,越短越好,这里与剃掉了几个大字版本:

$ perl -lne 'print "name: $1, value: $2" while /([A-Z]+)=(\d+)/gi' test.txt 
+0

太好了,谢谢!另外,似乎不需要在最后使用分号,这稍微减少了我在使用时需要输入的字符数。 – Erhannis

+0

@Erhannis对 - 对于块中的最后一条语句,分号是可选的。但是,如果您想要删除更多字符,请参阅我的更新回答。 –

+0

不要追求紧凑。如果您经常使用它,请改为编写脚本。 – Sobrique

1

我的建议是 - 考虑选择您的瓦尔成散列。

use Data::Dumper; 
local $/; 
my %stuff = <> =~ m/(\w+)=(\d+)/g; 
print Dumper \%stuff ; 

应该做大约你想要的。