[英]perl regex to remove dashes
我有一些正在处理的文件,我想从非日期字段中删除破折号。
我想出了s/([^0-9]+)-([^0-9]+)/$1 $2/g
但这仅在字符串中只有一个破折号的情况下有效,否则我会说仅删除一个破折号。
所以可以说我有:
2014-05-01
this-and
this-and-that
this-and-that-and-that-too
2015-01-01
我会用什么正则表达式来产生
2014-05-01
this and
this and that
this and that and that too
2015-01-01
不要用一个正则表达式来做。 不需要单个正则表达式必须包含所有代码逻辑。
使用一个正则表达式查看是否是日期,然后使用第二个进行转换。 如果将读者一分为二,它将对读者(将来就是您)更加清晰。
#!/usr/bin/perl
use warnings;
use strict;
while ( my $str = <DATA>) {
chomp $str;
my $old = $str;
if ( $str !~ /^\d{4}-\d{2}-\d{2}$/ ) { # First regex to see if it's a date
$str =~ s/-/ /g; # Second regex to do the transformation
}
print "$old\n$str\n\n";
}
__DATA__
2014-05-01
this-and
this-and-that
this-and-that-and-that-too
2015-01-01
运行可以为您提供:
2014-05-01
2014-05-01
this-and
this and
this-and-that
this and that
this-and-that-and-that-too
this and that and that too
2015-01-01
2015-01-01
使用环顾四周 :
$ perl -pe 's/
(?<!\d) # a negative look-behind with a digit: \d
- # a dash, literal
(?!\d) # a negative look-ahead with a digit: \d
/ /gx' file
2014-05-01
this and
this and that
this and that and that too
2015-01-01
查看一些断言,以确保-
周围没有数字(在这种情况下)。 环顾四周不会捕获任何东西,实际上只是在测试断言。 这是靠近您的好工具。
检查:
http://www.perlmonks.org/?node_id=518444
http://www.regular-expressions.info/lookaround.html
只要您的程序在$_
变量中分别接收每个字段,您所需要做的就是
tr/-/ / if /[^-\d]/
这应该做
$line =~ s/(\D)-/$1 /g;
正如我在评论中解释的那样,在编辑数据之前 ,您确实需要使用Text::CSV
将每个记录拆分为多个字段。 这是因为包含空格需要的数据被封闭在双引号,所以像场this-and-that
将开始进行不带空格,但需要时连字符被转换为空间添加他们。
该程序显示了一个使用您自己的数据的简单示例。
use strict;
use warnings;
use Text::CSV;
my $csv = Text::CSV->new({eol => $/});
while (my $row = $csv->getline(\*DATA)) {
for (@$row) {
tr/-/ / unless /^\d\d\d\d-\d\d-\d\d$/;
}
$csv->print (\*STDOUT, $row);
}
__DATA__
2014-05-01,this-and-that,this-and-that,this-and-that-and-that-too,2015-01-01
输出
2014-05-01,"this and that","this and that","this and that and that too",2015-01-01
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.