首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >perl中的模式匹配

perl中的模式匹配
EN

Stack Overflow用户
提问于 2014-09-08 18:09:43
回答 4查看 83关注 0票数 1
代码语言:javascript
复制
my $line = "Name:Amanda_Marry_Rose,Region:US,host:USE,cardType:DebitCard,product:Satin,Name:Raghav.S.Thomas,Region:UAE,";
my $name = "";

@name = ( $line =~ m/Name:([\w\s\_\,/g );
foreach (@name) {
   print $name."\n";
}

我希望捕获Name:,Region之间的单词,无论它出现在整个代码行中的哪个位置。主要的漏洞是名称可以是任何格式

代码语言:javascript
复制
Amanda_Marry_Rose
Amanda.Marry.Rose
Amanda Marry Rose
Amanda/Marry/Rose

我需要一个帮助来捕获这样的模式,每次它出现在生产线上。因此,对于我提供的行,输出应该是

代码语言:javascript
复制
Amanda_Marry_Rose
Raghav.S.Thomas

有谁知道怎么做吗?我试着保持下面这一行,但它给我的输出是错误的。

代码语言:javascript
复制
@name=($line=~m/Name:([\w\s\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\`\{\|\}\~\´]+)\,/g);

输出

代码语言:javascript
复制
Amanda_Marry_Rose,Region:US,host:USE,cardType:DebitCard,product:Satin,Name:Raghav.S.Thomas,Region:UAE
EN

回答 4

Stack Overflow用户

发布于 2014-09-08 18:50:00

要在Name:和第一个逗号之间进行捕获,请使用negated character class

代码语言:javascript
复制
/Name:([^,]+)/g

这表示匹配Name:后面的一个或多个不是逗号的字符:

代码语言:javascript
复制
while (/Name:([^,]+)/g) {
    print $1, "\n";
}

这比非贪婪的quantifier更有效,例如:

代码语言:javascript
复制
/Name:(.+?),/g

因为它不需要backtracking

票数 3
EN

Stack Overflow用户

发布于 2014-09-08 18:20:29

Reg-ex已更正:

代码语言:javascript
复制
my $line = "Name:Amanda_Marry_Rose,Region:US,host:USE,cardType:DebitCard,product:Satin,Name:Raghav.S.Thomas,Region:UAE,";

my @name = ($line =~ /Name\:([\w\s_.\/]+)\,/g);
    foreach my $name (@name) {
    print $name."\n";
}
票数 0
EN

Stack Overflow用户

发布于 2014-09-08 22:05:11

您所拥有的是逗号分隔的数据。应该如何解析它在很大程度上取决于您的数据。如果是完整的csv数据,最安全的方法是使用适当的csv解析器,比如Text::CSV。如果是不太严格的数据,您可以使用轻量级解析器Text::ParseWords,它的好处还在于它是Perl5中的核心模块。如果这里提供的是相当基本的用户输入字段,那么我建议使用split --这只是因为当您知道分隔符时,定义它比定义其中的所有其他分隔符都更容易、更安全。

代码语言:javascript
复制
use strict;
use warnings;
use Data::Dumper;

my $line = "Name:Amanda_Marry_Rose,Region:US,host:USE,cardType:DebitCard,product:Satin,Name:Raghav.S.Thomas,Region:UAE,";

# Simple split
my @fields = split /,/, $line;
print Dumper for map /^Name:(.*)/, @fields;

use Text::ParseWords;
print Dumper map /^Name:(.*)/, quotewords(',', 0, $line);

use Text::CSV;
my $csv = Text::CSV->new({
        binary => 1,
    });
$csv->parse($line);
print Dumper map /^Name:(.*)/, $csv->fields;

除了使用Text::CSV的选项之外,所有这些选项都会给出相同的输出,它也会非常正确地发出一个未定义的警告,因为您的数据有一个尾随的逗号(意思是末尾有一个空字段)。

每种方法都有不同的优点和缺点。Text::CSV可能会被不符合CSV格式的数据阻塞,并且split无法处理嵌入的逗号,如Name:"Doe, John",...

我们用来非常简单地提取名称的正则表达式只捕获以Name:开头的整个其余行。这还允许您对字段名称执行完整性检查,例如,如果突然发现名为Doe;Name:的字段,则会发出警告

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25721855

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档