我正在处理一些文件,我想从非日期字段中删除破折号。
我提出了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
答案 0 :(得分:5)
不要使用一个正则表达式。不要求单个正则表达式必须包含所有代码的逻辑。
使用一个正则表达式查看它是否为日期,然后使用第二个正则表达式进行转换。如果你把它分成两部分,读者会更清楚(将来就是你)。
#!/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
答案 1 :(得分:2)
使用look around:
$ 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
答案 2 :(得分:1)
答案 3 :(得分:1)
只要您的程序在$_
变量中单独收到每个字段,您只需要
tr/-/ / if /[^-\d]/
答案 4 :(得分:0)
这应该这样做
$line =~ s/(\D)-/$1 /g;
答案 5 :(得分:0)
正如我在评论中所解释的那样,在编辑数据之前,您确实需要使用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
答案 6 :(得分:-1)
如果您想要排除特定表单的更改,您必须包含它们 在搜索时在正则表达式中。否则,你不能确定。
# s/((?:\d{4}\s*-\s*\d{2}\s*-\s*\d{2}[^\d-]*)*)-((?:[^\d-]*\d{4}\s*-\s*\d{2}\s*-\s*\d{2})*)/$1 $2/g
( # (1 start)
(?:
\d{4} \s* - \s* \d{2} \s* - \s* \d{2}
[^\d-]*
)*
) # (1 end)
-
( # (2 start)
(?:
[^\d-]*
\d{4} \s* - \s* \d{2} \s* - \s* \d{2}
)*
) # (2 end)